[{"data":1,"prerenderedAt":1092},["ShallowReactive",2],{"\u002Fblog\u002Fmakieta-nuxt-supabase":3,"\u002Fblog\u002Fmakieta-nuxt-supabase-surround":1081},{"id":4,"title":5,"author":6,"body":7,"date":1069,"description":1070,"draft":1071,"extension":1072,"image":1073,"meta":1074,"minRead":1075,"navigation":320,"path":1076,"seo":1077,"sitemap":1078,"stem":1079,"__hash__":1080},"blog\u002Fblog\u002Fmakieta-nuxt-supabase.md","Dwa dni robocze, jeden działający prototyp","Artur Wilczek",{"type":8,"value":9,"toc":1052},"minimark",[10,15,33,36,39,42,46,53,84,94,98,121,132,143,151,157,193,209,452,456,479,487,496,500,503,529,538,543,629,633,672,676,721,725,746,750,809,813,928,932,988,992,1030,1034,1037,1048],[11,12,14],"h2",{"id":13},"po-co-prototyp-lub-mvp","Po co prototyp lub MVP?",[16,17,18,22,23,32],"p",{},[19,20,21],"strong",{},"MVP"," - Minimum Viable Product - najprostsza, funkcjonalna wersja aplikacji, która zawiera jedynie podstawowe funkcje pozwalające rozwiązać kluczowy problem użytkowników. Pojęcie popularne w świecie ",[19,24,25],{},[26,27,31],"a",{"href":28,"rel":29},"https:\u002F\u002Fpl.wikipedia.org\u002Fwiki\u002FOprogramowanie_jako_us%C5%82uga",[30],"nofollow","SaaS",", ale ma też zastosowanie przy podejściu do tworzenia aplikacji z szybkim prototypowaniem.",[16,34,35],{},"Z doświadczenia wiem, że nawet po wielu godzinach spotkań z przyszłym użytkownikiem aplikacji, przygotowywania koncepcji i architektury rozwiązania, kluczowe pomysły i najwięcej uwag do produktu pojawia się po oddaniu aplikacji do testów, a nawet częściej po oddaniu aplikacji do użytku.",[16,37,38],{},"Dzisiaj mamy do dyspozycji narzędzia i technologie, które pozwalają, w bardzo krótkim czasie, przygotować makietę aplikacji, w której użytkownik może wykonywać lub symulować rzeczywiste operacje biznesowe, zgodne z założeniami procesu, który ta aplikacja ma obsługiwać i wspierać. W ten sposób użytkownik bierze czynny udział w procesie tworzenia, a wszystkie zgłaszane rozwiązania lub modyfikacje mogą zostać sprawnie zaimplementowane i oddane do kolejnych testów.",[16,40,41],{},"Jeśli pracujemy dla nowego, zewnętrznego klienta, który jeszcze nie do końca nam ufa i nie chce ponosić dużych kosztów na początku współpracy, możemy szybko zdefiniować główne założenia projektowe, równie szybko przygotować prototyp i bez ingerencji w jego infrastrukturę, udostępnić prototyp na własnej platformie (jeśli takową dysponujemy) lub skorzystać z jednej z wielu publicznie dostępnych platform hostingowych. W przypadku platform Internetowych, makietę aplikacji błyskawicznie wypełniamy fikcyjnymi i sztucznie wygenerowanymi danymi, nie narażając klienta na wyciek poufnych danych biznesowych.",[11,43,45],{"id":44},"co-udało-się-zrobić-w-tak-krótkim-czasie","Co udało się zrobić w tak krótkim czasie?",[16,47,48,49,52],{},"Na potrzeby tego artykułu poświęciłem ",[19,50,51],{},"dwa dni robocze",", żeby przygotować pokazowy prototyp aplikacji, która z założenia może pracować w rejestracji lub sekretariacie placówki medycznej. W tak krótkim czasie udało się wdrożyć funkcje takie jak:",[54,55,56,60,63,66,69,72,75,78,81],"ul",{},[57,58,59],"li",{},"lista specjalizacji medycznych",[57,61,62],{},"dodawanie nowych lekarzy",[57,64,65],{},"prezentacja lekarzy w formie tabeli z możliwością sortowania\u002Ffiltrowania",[57,67,68],{},"dodawanie nowych pacjentów",[57,70,71],{},"prezentacja pacjentów w formie tabeli z możliwością sortowania\u002Ffiltrowania",[57,73,74],{},"definiowanie dostępności lekarzy",[57,76,77],{},"rezerwowanie wizyt pacjentów",[57,79,80],{},"wizualizacja danych związanych z lekarzem: dane podstawowe, dostępność, wizyty zaplanowane i archiwalne, pacjenci powiązani relacją pacjent-lekarz rodzinny, rejestr zdarzeń",[57,82,83],{},"wizualizacja danych związanych z pacjentem: dane podstawowe, wizyty zaplanowane i archiwalne, rejestr zdarzeń",[16,85,86,87,93],{},"Na końcu tego artykułu udostępniam ",[19,88,89],{},[26,90,92],{"href":91},"#materia%C5%82-wideo","materiał wideo",", na którym demonstruję co potrafi prototyp.",[11,95,97],{"id":96},"jak-to-w-ogóle-możliwe-w-tak-krótkim-czasie","Jak to w ogóle możliwe w tak krótkim czasie?",[16,99,100,101,104,105,112,113,120],{},"Takie możliwości dają oczywiście duże modele językowe, z których, coraz sprawniej, korzystają ",[19,102,103],{},"agenci \u002F asystenci AI"," dedykowani do wykonywania prac programistycznych. Osobiście używam ",[19,106,107],{},[26,108,111],{"href":109,"rel":110},"https:\u002F\u002Fgithub.com\u002Ffeatures\u002Fcopilot",[30],"GitHub Copilot Pro"," zintegrowanego z ",[19,114,115],{},[26,116,119],{"href":117,"rel":118},"https:\u002F\u002Fcode.visualstudio.com\u002F",[30],"VS Code",".",[16,122,123,124,131],{},"Stosując tradycyjne techniki programistyczne, nie jestem w stanie dostarczyć prototypu w tak krótkim czasie. Mogę zaryzykować stwierdzenie, że tak samo trudno byłoby uzyskać podobny efekt stosując platformę typu ",[19,125,126],{},[26,127,130],{"href":128,"rel":129},"https:\u002F\u002Fpl.wikipedia.org\u002Fwiki\u002FPlatforma_niskokodowa",[30],"low-code",", w której, co prawda, buduje się szybko podstawowe funkcjonalności z gotowych klocków, ale przy implementacji bardziej skomplikowanej logiki biznesowej, na drodze stają ograniczenia lub specyfika platformy.",[16,133,134,135,142],{},"Z pomocą przychodzą też coraz bardziej popularne protokół i serwery ",[19,136,137],{},[26,138,141],{"href":139,"rel":140},"https:\u002F\u002Fpl.wikipedia.org\u002Fwiki\u002FModel_Context_Protocol#",[30],"MCP",", które dają agentowi AI dostęp, na przykład do:",[54,144,145,148],{},[57,146,147],{},"aktualnej dokumentacji narzędzi lub technologii, których używam w czasie przygotowywania prototypu",[57,149,150],{},"narzędzi platform bazodanowych, które pozwalają kreować obiekty DB stosując język naturalny",[16,152,153,154,156],{},"W tym projekcie korzystałem z trzech serwerów ",[19,155,141],{},":",[54,158,159,169,178],{},[57,160,161,162],{},"dokumentacja ",[19,163,164],{},[26,165,168],{"href":166,"rel":167},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fguide\u002Fai\u002Fmcp",[30],"Nuxt",[57,170,161,171],{},[19,172,173],{},[26,174,177],{"href":175,"rel":176},"https:\u002F\u002Fui.nuxt.com\u002Fdocs\u002Fgetting-started\u002Fai\u002Fmcp",[30],"Nuxt UI",[57,179,180,181,188,189,192],{},"narzędzia platformy bazodanowej ",[19,182,183],{},[26,184,187],{"href":185,"rel":186},"https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fgetting-started\u002Fmcp",[30],"Supabase"," (",[19,190,191],{},"PostgreSQL"," w chmurze)",[16,194,195,196,201,202,205,206,156],{},"Konfiguracja w ",[19,197,198],{},[26,199,119],{"href":117,"rel":200},[30]," jest prosta i wymaga przygotowania pliku ",[19,203,204],{},"mcp.json"," w folderze ",[19,207,208],{},".vscode",[210,211,217],"pre",{"className":212,"code":213,"filename":214,"language":215,"meta":216,"style":216},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"servers\": {\n    \"NUXT UI\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Fui.nuxt.com\u002Fmcp\"\n    },\n\n    \"NUXT\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Fnuxt.com\u002Fmcp\"\n    },\n\n    \"SUPABASE\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Fmcp.supabase.com\u002Fmcp?project_ref=klnuspxlvrxjhudrxcro\"\n    }\n  }\n}\n",".vscode\\mcp.json","json","",[218,219,220,229,247,263,289,309,315,322,336,355,373,378,383,397,416,434,440,446],"code",{"__ignoreMap":216},[221,222,225],"span",{"class":223,"line":224},"line",1,[221,226,228],{"class":227},"sMK4o","{\n",[221,230,232,235,239,242,244],{"class":223,"line":231},2,[221,233,234],{"class":227},"  \"",[221,236,238],{"class":237},"spNyl","servers",[221,240,241],{"class":227},"\"",[221,243,156],{"class":227},[221,245,246],{"class":227}," {\n",[221,248,250,253,257,259,261],{"class":223,"line":249},3,[221,251,252],{"class":227},"    \"",[221,254,256],{"class":255},"sBMFI","NUXT UI",[221,258,241],{"class":227},[221,260,156],{"class":227},[221,262,246],{"class":227},[221,264,266,269,273,275,277,280,284,286],{"class":223,"line":265},4,[221,267,268],{"class":227},"      \"",[221,270,272],{"class":271},"sbssI","type",[221,274,241],{"class":227},[221,276,156],{"class":227},[221,278,279],{"class":227}," \"",[221,281,283],{"class":282},"sfazB","http",[221,285,241],{"class":227},[221,287,288],{"class":227},",\n",[221,290,292,294,297,299,301,303,306],{"class":223,"line":291},5,[221,293,268],{"class":227},[221,295,296],{"class":271},"url",[221,298,241],{"class":227},[221,300,156],{"class":227},[221,302,279],{"class":227},[221,304,305],{"class":282},"https:\u002F\u002Fui.nuxt.com\u002Fmcp",[221,307,308],{"class":227},"\"\n",[221,310,312],{"class":223,"line":311},6,[221,313,314],{"class":227},"    },\n",[221,316,318],{"class":223,"line":317},7,[221,319,321],{"emptyLinePlaceholder":320},true,"\n",[221,323,325,327,330,332,334],{"class":223,"line":324},8,[221,326,252],{"class":227},[221,328,329],{"class":255},"NUXT",[221,331,241],{"class":227},[221,333,156],{"class":227},[221,335,246],{"class":227},[221,337,339,341,343,345,347,349,351,353],{"class":223,"line":338},9,[221,340,268],{"class":227},[221,342,272],{"class":271},[221,344,241],{"class":227},[221,346,156],{"class":227},[221,348,279],{"class":227},[221,350,283],{"class":282},[221,352,241],{"class":227},[221,354,288],{"class":227},[221,356,358,360,362,364,366,368,371],{"class":223,"line":357},10,[221,359,268],{"class":227},[221,361,296],{"class":271},[221,363,241],{"class":227},[221,365,156],{"class":227},[221,367,279],{"class":227},[221,369,370],{"class":282},"https:\u002F\u002Fnuxt.com\u002Fmcp",[221,372,308],{"class":227},[221,374,376],{"class":223,"line":375},11,[221,377,314],{"class":227},[221,379,381],{"class":223,"line":380},12,[221,382,321],{"emptyLinePlaceholder":320},[221,384,386,388,391,393,395],{"class":223,"line":385},13,[221,387,252],{"class":227},[221,389,390],{"class":255},"SUPABASE",[221,392,241],{"class":227},[221,394,156],{"class":227},[221,396,246],{"class":227},[221,398,400,402,404,406,408,410,412,414],{"class":223,"line":399},14,[221,401,268],{"class":227},[221,403,272],{"class":271},[221,405,241],{"class":227},[221,407,156],{"class":227},[221,409,279],{"class":227},[221,411,283],{"class":282},[221,413,241],{"class":227},[221,415,288],{"class":227},[221,417,419,421,423,425,427,429,432],{"class":223,"line":418},15,[221,420,268],{"class":227},[221,422,296],{"class":271},[221,424,241],{"class":227},[221,426,156],{"class":227},[221,428,279],{"class":227},[221,430,431],{"class":282},"https:\u002F\u002Fmcp.supabase.com\u002Fmcp?project_ref=klnuspxlvrxjhudrxcro",[221,433,308],{"class":227},[221,435,437],{"class":223,"line":436},16,[221,438,439],{"class":227},"    }\n",[221,441,443],{"class":223,"line":442},17,[221,444,445],{"class":227},"  }\n",[221,447,449],{"class":223,"line":448},18,[221,450,451],{"class":227},"}\n",[11,453,455],{"id":454},"czy-faktycznie-zaczynałem-od-zera","Czy faktycznie zaczynałem od zera?",[16,457,458,459,465,466,470,471,474,475,478],{},"Jeśli chodzi o platformę ",[19,460,461],{},[26,462,187],{"href":463,"rel":464},"https:\u002F\u002Fsupabase.com",[30],", to rzeczywiście tak - utworzyłem nowy, pusty projekt. Wszystkie obiekty DB, takie jak: tabele, polityki ",[467,468,469],"em",{},"RLS",", funkcje, ",[467,472,473],{},"trigger-y",", funkcje typu ",[467,476,477],{},"edge",", tworzyłem wydając agentowi polecenia w języku naturalnym. To samo jeśli chodzi o wypełnianie tabel fikcyjnymi danymi.",[480,481,482],"warning",{},[16,483,484],{},[467,485,486],{},"Na potrzeby artykułu i aplikacji pokazowej, stosuję polskie nazwy tabel i pól. W realnym świecie raczej stosuje się nazewnictwo w języku angielskim.",[16,488,489,490,493,494,120],{},"Jeśli chodzi o ",[19,491,492],{},"frontend web","-owy, to na start użyłem własnego szablonu, który jest minimalnym szkieletem interfejsu użytkownika i zawiera tylko górną belkę, lewy panel menu (pusty), główną przestrzeń roboczą (pustą), okno logowania i rejestracji użytkownika oraz podstawową integrację z platformą ",[19,495,187],{},[11,497,499],{"id":498},"na-czym-polegała-moja-praca","Na czym polegała moja praca?",[16,501,502],{},"Głównie na wymyślaniu architektury, definiowaniu zadań dla mojego agenta oraz weryfikowaniu i testowaniu wyników jego pracy.",[16,504,505,506,509,510,188,513,516,517,520,521,524,525,528],{},"Wszystkie polecenia dla agenta zapisywałem w notatkach i uzbierało się tego około ",[19,507,508],{},"100"," zadań, co przy ",[19,511,512],{},"dwóch dniach",[19,514,515],{},"960"," minut) intensywnych prac, daje średnio ponad ",[19,518,519],{},"9,5"," minuty na jedno zadanie. Zdecydowana większość prompt-ów była jednozdaniowymi, precyzyjnymi poleceniami, których napisanie zajmowało mniej niż ",[19,522,523],{},"1"," minutę, wykonanie agenta to ",[19,526,527],{},"2-3"," minuty, reszta to była moja weryfikacja i szybkie testy. Zdarzały się też bardziej rozbudowane polecenia, które, na przykład, definiowały skomplikowaną logikę i nie miało sensu dzielić ich na mniejsze porcje, co dawało asystentowi lepsze trzymanie kontekstu. Tak na marginesie, agent sam dzielił większe zadanie na mniejsze podzadania oraz ustalał prawidłową kolejność ich realizacji.",[16,530,531,532,534,535,120],{},"Poniżej kilka ciekawszych zadań \u002F prompt-ów, zarówno tych dla bazy danych ",[19,533,187],{}," oraz frontend-u ",[19,536,537],{},"Nuxt \u002F Nuxt UI",[539,540,542],"h3",{"id":541},"utworzenie-dwóch-tabel-w-db-zdefiniowanie-relacji-oraz-insert-testowych-danych","Utworzenie dwóch tabel w DB, zdefiniowanie relacji oraz INSERT testowych danych:",[544,545,546,549,585,587,614,626],"blockquote",{},[16,547,548],{},"Potrzebuję w bazie danych nowej tabeli:",[54,550,551,557,572],{},[57,552,553,554],{},"nazwa tabeli: ",[19,555,556],{},"lekarze",[57,558,559,560,563,564,567,568,571],{},"pola: ",[19,561,562],{},"id",", ",[19,565,566],{},"imie"," (text, not null), ",[19,569,570],{},"nazwisko"," (text, not null)",[57,573,574,575,563,578,563,581,584],{},"włącz politykę RLS: ",[19,576,577],{},"SELECT",[19,579,580],{},"INSERT",[19,582,583],{},"UPDATE"," dla zalogowanych użytkowników",[16,586,548],{},[54,588,589,595,606,611],{},[57,590,591,592],{},"nazwa: ",[19,593,594],{},"specjalizacje",[57,596,559,597,563,599,567,602,605],{},[19,598,562],{},[19,600,601],{},"specjalizacja",[19,603,604],{},"is_active"," (boolean, domyślnie true)",[57,607,608,609,584],{},"włącz politykę RLS: tylko ",[19,610,577],{},[57,612,613],{},"wypełnij tabelę 30 specjalizacjami lekarskimi",[16,615,616,617,619,620,623,624,120],{},"Do tabeli ",[19,618,556],{}," dodaj pole ",[19,621,622],{},"id_specjalizacji"," jako klucz obcy do tabeli ",[19,625,594],{},[16,627,628],{},"Dodaj 100 lekarzy do tabeli lekarze z różnych specjalizacji.",[539,630,632],{"id":631},"rozbudowa-strony-z-tabelą-specjalizacji","Rozbudowa strony z tabelą specjalizacji:",[544,634,635,641],{},[16,636,637,638,156],{},"Strona ",[19,639,640],{},"\u002Fspecjalizacje",[54,642,643,653,661,667],{},[57,644,645,646,649,650],{},"w kolumnie ",[19,647,648],{},"Status"," wartość prezentuje komponent ",[19,651,652],{},"UBadge",[57,654,655,656,658,659],{},"zostaw go, ale zrób z niego link, którym można zmienić (toggle) wartość w polu ",[19,657,604],{}," tabeli ",[19,660,594],{},[57,662,663,664],{},"obsługa zmiany wartości, komunikaty podobnie jak na stronie ",[19,665,666],{},"\u002Flekarze",[57,668,669,670],{},"dodaj możliwość sortowania po kolumnie ",[19,671,648],{},[539,673,675],{"id":674},"nowa-strona-ze-szczegółami-lekarza","Nowa strona ze szczegółami lekarza:",[544,677,678,684,708],{},[16,679,680,681,156],{},"Nowa strona ",[19,682,683],{},"\u002Flekarze\u002F:id",[54,685,686,689,699,702,705],{},[57,687,688],{},"dodaj stronę",[57,690,691,692,694,695,698],{},"w tabeli lekarzy na stronie ",[19,693,666],{}," jest kolumna ",[19,696,697],{},"ID"," - zrób z niej link do nowej strony",[57,700,701],{},"na stronie formularz read-only z danymi lekarza",[57,703,704],{},"poniżej formularza, tabela zdarzeń związanych z lekarzem",[57,706,707],{},"tabela zdarzeń w prostej formie, sortowanie po dacie malejąco, bez możliwości sortowanie i filtrowania",[16,709,710,711,714,715,205,718,720],{},"Nie działają linki do nowej strony. Może trzeba plik ",[19,712,713],{},"lekarze.vue"," zmienić na ",[19,716,717],{},"index.vue",[19,719,556],{},"?",[539,722,724],{"id":723},"korekta-formularza-dodawania-nowego-lekarza","Korekta formularza dodawania nowego lekarza:",[544,726,727],{},[16,728,729,730,733,734,737,738,741,742,745],{},"Zmień układ formularza tak aby pola pojawiały się na przemiennie w dwóch kolumnach o tej samej szerokości (użyj ",[19,731,732],{},"grid",").\nPola typu ",[19,735,736],{},"input"," czy ",[19,739,740],{},"select"," powinny zajmować całą szerokość kolumny.\nWszystkie błędy i sukcesy pokazuj za pomocą ",[19,743,744],{},"toast",".\nRozbuduj walidację: z listy lekarzy rodzinnych musi być wybrana pozycja.\nLista rozwijana lekarza rodzinnego jest bardzo długa. Dodaj możliwość filtrowania po nazwisku.",[539,747,749],{"id":748},"nowa-tabela-z-mechanizmem-seed","Nowa tabela z mechanizmem seed:",[544,751,752,755],{},[16,753,754],{},"Nowa tabela w bazie danych:",[54,756,757,762,770,774,798],{},[57,758,553,759],{},[19,760,761],{},"dni",[57,763,559,764,563,766,769],{},[19,765,562],{},[19,767,768],{},"dzien"," (text, not null, unique)",[57,771,608,772,584],{},[19,773,577],{},[57,775,776,777,780,781],{},"utwórz mechanizm ",[19,778,779],{},"seed"," dla tabeli, tak żeby wstawiał lub aktualizował następujące rekordy:\n",[54,782,783,786,789,792,795],{},[57,784,785],{},"id: 1; dzien: Poniedziałek",[57,787,788],{},"id: 2; dzien: Wtorek",[57,790,791],{},"id: 3; dzien: Środa",[57,793,794],{},"id: 4; dzien: Czwartek",[57,796,797],{},"id: 5; dzien: Piątek",[57,799,800,801,658,803,805,806,120],{},"Mechanizm ",[19,802,779],{},[19,804,761],{}," zrób jako funkcja bazy danych podobnie jak funkcja ",[19,807,808],{},"seed_event_types",[539,810,812],{"id":811},"funkcja-brzegowa-realizująca-logikę-planowania-wizyty-lekarskiej","Funkcja brzegowa realizująca logikę planowania wizyty lekarskiej:",[544,814,815,818,836,841,915,920],{},[16,816,817],{},"Nowa funkcja brzegowa (edge function):",[54,819,820,825],{},[57,821,591,822],{},[19,823,824],{},"zaplanuj_wizyte",[57,826,827,828,563,831,563,834],{},"argumenty: ",[19,829,830],{},"lekarz_id",[19,832,833],{},"pacjent_id",[19,835,768],{},[16,837,838,839,156],{},"Logika funkcji ",[19,840,824],{},[54,842,843,846,852,857,860,863,868,874,881,892,898,907],{},[57,844,845],{},"sprawdź, czy wywołanie funkcji jest w kontekście zalogowanego użytkownika, jeśli nie to błąd",[57,847,848,849,851],{},"sprawdź, czy istnieje lekarz o ",[19,850,830],{},", jeśli nie to błąd",[57,853,854,855,851],{},"sprawdź, czy istnieje pacjent o ",[19,856,833],{},[57,858,859],{},"dzień może być dzisiaj lub w przyszłości, jeśli nie to błąd",[57,861,862],{},"na podstawie daty ustal jaki to dzień tygodnia (Poniedziałek to 1)",[57,864,865,866,851],{},"sprawdź, czy istnieje taki dzień w tabeli ",[19,867,761],{},[57,869,870,871,851],{},"sprawdź, czy lekarz ma ten dzień tygodnia ustaloną dostępność w tabeli ",[19,872,873],{},"dostepnosc_lekarza",[57,875,876,877,880],{},"odczytaj wszystkie rekordy z tabeli ",[19,878,879],{},"wizyty"," dla lekarza na tę datę posortowane rosnąco po godzinie",[57,882,883,884,887,888,891],{},"ustal pierwszą godzinę dostępności lekarza bazując na zdefiniowanej dostępności w ",[19,885,886],{},"dostępnosc_lekarza",", biorąc pod uwagę godzinę startową oraz czas potrzebny na pacjenta (pole ",[19,889,890],{},"czas_na_pacjenta","); jeśli nie udało się ustalić wolnej godziny (np. z powodu braku miejsc) to błąd",[57,893,894,895,897],{},"dodaj rekord do tabeli ",[19,896,879],{},", w pole godzina wstaw ustaloną godzinę pierwszej możliwej wizyty",[57,899,894,900,563,903,906],{},[19,901,902],{},"lekarze_zdarzenia",[19,904,905],{},"zdarzenie_id"," = 5, opis = Pacjent: Nazwisko Imię pacjenta + data i godzina wizyty",[57,908,894,909,563,912,914],{},[19,910,911],{},"pacjenci_zdarzenia",[19,913,905],{}," = 5, opis = Pacjent: Nazwisko Imię lekarza + data i godzina wizyty",[16,916,838,917,919],{},[19,918,824],{}," - rozbudowa:",[54,921,922,925],{},[57,923,924],{},"sprawdzaj, czy lekarz jest aktywny, jeśli nie to błąd",[57,926,927],{},"dodaj kontrolę, która pozwala na zaplanowanie pacjentowi tylko jednej wizyty w danym dniu",[539,929,931],{"id":930},"szybka-migracja-zarządzania-stanem-do-pinia-store","Szybka migracja zarządzania stanem do Pinia Store:",[544,933,934,942,968,975],{},[16,935,637,936,938,939,156],{},[19,937,683],{}," - migracja do ",[19,940,941],{},"Pinia Store",[54,943,944,950,956,965],{},[57,945,946,947],{},"strona ma wiele elementów, które potrzebują danych z ",[19,948,949],{},"Supabase REST API",[57,951,952,953,955],{},"wszystkie dane potrzebne na tej stronie, łącznie z zagnieżdżonymi komponentami, mają korzystać z globalnego ",[19,954,941],{}," reprezentującego dane lekarza",[57,957,958,959,961,962],{},"wszystkie wywołania ",[19,960,949],{}," mają znaleźć się w akcjach ",[19,963,964],{},"store",[57,966,967],{},"wykonanie akcji takich jak zakończenie wizyty, odwołanie wizyty, usunięcie dostępności, ustalenie dostępności powinny inicjować odświeżenie tabeli historii zdarzeń lekarza",[16,969,637,970,938,973,156],{},[19,971,972],{},"\u002Fpacjenci\u002F:id",[19,974,941],{},[54,976,977,985],{},[57,978,979,980,982,983],{},"podobnie jak dla lekarzy, migruj do ",[19,981,941],{}," obsługę stanu i komunikacji z ",[19,984,949],{},[57,986,987],{},"akcje takie jak zakończenie wizyty, odwołanie wizyty, powinny inicjować odświeżenie tabeli historii zdarzeń pacjenta",[539,989,991],{"id":990},"przykłady-prompt-ów-korygujących-agenta-czyli-strofowanie-asystenta","Przykłady prompt-ów korygujących agenta, czyli strofowanie asystenta:",[544,993,994,1001,1007,1013,1016],{},[16,995,996,997,1000],{},"Sprawdź komponent ",[19,998,999],{},"UPagination",", stronicowanie dalej nie działa.",[16,1002,1003,1004,120],{},"Nie działa wywołanie okna dialogowego, nie użyto ",[19,1005,1006],{},"useOverlay",[16,1008,1009,1010,120],{},"Okno dialogowe otwiera się, ale nic się nie pokazuje. Sprawdź dokumentację ",[19,1011,1012],{},"UModal",[16,1014,1015],{},"Lista rozwijana lekarzy rodzinnych nie pokazuje wartości do wyboru.",[16,1017,1018,1019,1022,1023,1026,1027,120],{},"Nie podoba mi się rozwiązanie z natywnym ",[19,1020,1021],{},"form",". Użyj ",[19,1024,1025],{},"UForm",", który umożliwia integracje ze schematem walidacji ",[19,1028,1029],{},"zod",[11,1031,1033],{"id":1032},"materiał-wideo","Materiał wideo",[16,1035,1036],{},"Nagranie demonstrujące co potrafi 2-dniowy prototyp.",[1038,1039,1041,1042,1047],"video",{"controls":320,"width":1040},800,"\n  ",[1043,1044],"source",{"src":1045,"type":1046},"https:\u002F\u002Fdr.awfs.dev\u002Fvideos\u002Fproto-app-001.mp4","video\u002Fmp4","\n  Twoja przeglądarka nie wspiera odtwarzania wideo.\n",[1049,1050,1051],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":216,"searchDepth":231,"depth":231,"links":1053},[1054,1055,1056,1057,1058,1068],{"id":13,"depth":231,"text":14},{"id":44,"depth":231,"text":45},{"id":96,"depth":231,"text":97},{"id":454,"depth":231,"text":455},{"id":498,"depth":231,"text":499,"children":1059},[1060,1061,1062,1063,1064,1065,1066,1067],{"id":541,"depth":249,"text":542},{"id":631,"depth":249,"text":632},{"id":674,"depth":249,"text":675},{"id":723,"depth":249,"text":724},{"id":748,"depth":249,"text":749},{"id":811,"depth":249,"text":812},{"id":930,"depth":249,"text":931},{"id":990,"depth":249,"text":991},{"id":1032,"depth":231,"text":1033},"2025-11-17","W dwa dni robocze, z pomocą Copilot-a i MCP, zbudowałem działającą makietę aplikacji medycznej.",false,"md","\u002Fpics\u002F0003.png",{"order":249},null,"\u002Fblog\u002Fmakieta-nuxt-supabase",{"title":5,"description":1070},{"loc":1076},"blog\u002Fmakieta-nuxt-supabase","K_4whd6HA7Wb9x6BDFE-jzVwYxPFhBO0vvMmhk-bZ08",[1082,1087],{"title":1083,"path":1084,"stem":1085,"description":1086,"children":-1},"AI for coding? Nie ma ucieczki!","\u002Fblog\u002Fai-for-coding","blog\u002Fai-for-coding","GitHub Copilot pisze za mnie klasę do obsługi skrzynki pocztowej MS Exchange",{"title":1088,"path":1089,"stem":1090,"description":1091,"children":-1},"AI-Driven Development Workflow","\u002Fblog\u002Fai-driven-development-workflow","blog\u002Fai-driven-development-workflow","Buduję zespół agentów \u002F specjalistów Claude Code, ustalam flow procesu produkcji i utrzymania nowej aplikacji.",1780996675131]