Book Notes — osobisty katalog przeczytanych książek
Prosta aplikacja webowa do prowadzenia własnego katalogu lektur. Okładki pobierane automatycznie z Open Library API przez ISBN, notatki i opisy edytowane bezpośrednio na stronie bez przeładowania, sortowanie po tytule, dacie lub ocenie — wszystko w klasycznym server-side rendering: Express + EJS + PostgreSQL.
01Wygląd aplikacji
Celowo minimalistyczna estetyka — biała strona, Georgia serif, maksymalna szerokość 40em. Wygląd klasycznego bloga książkowego: zero kolorowych elementów, zero ikon, tylko tekst i okładki. Aplikacja ma dwa widoki: listę wszystkich książek i stronę szczegółów pojedynczej książki.
Widok listy — strona główna
cover
ISBN
cover
ISBN
cover
ISBN
strona główna — lista książek posortowana według oceny rekomendacji
Strona szczegółów — tryb czytania
cover by
ISBN
strona szczegółów — widok notatek w trybie czytania
Strona szczegółów — tryb edycji
Kliknięcie przycisku Edit book details ukrywa paragrafy
i odkrywa <textarea> z aktualną treścią — bez przeładowania strony,
czystym JavaScriptem DOM API. Zapis przez standardowy formularz POST.
cover by
ISBN
tryb edycji — teksty zamieniają się w textarea, przycisk ✓ zapisuje zmiany
02Jak działa aplikacja
Aplikacja używa wzorca POST → redirect → GET do wszystkich operacji.
Kliknięcie tytułu lub “Read my notes” wysyła ukryty formularz POST z bookId,
serwer pobiera dane z PostgreSQL i renderuje stronę szczegółów przez EJS.
Sortowanie to osobny formularz POST do /sort z ukrytym polem sortType.
- Okładki przez Open Library — URL
covers.openlibrary.org/b/isbn/{isbn}-M.jpgwstawiany przez EJS w atrybutsrcobrazu. Przeglądarka sama pobiera okładkę bezpośrednio — żadnych requestów z Node.js. - Trzy tryby sortowania — jeden endpoint
POST /sort, trzy zapytania SQL z różnymORDER BY: tytuł ASC, data DESC, ocena DESC. - Inline edit bez przeładowania — kliknięcie “Edit” wywołuje
handler(), który ukrywa paragrafy i pokazuje textarea przezsetAttribute/removeAttribute("hidden"). - Potwierdzenie usunięcia —
confirmDelete()wywołuje przeglądarkowyconfirm()przed wysłaniem formularza DELETE.
-- Trzy warianty sortowania — jeden endpoint, różne ORDER BY
SELECT * FROM books ORDER BY title ASC; -- "title"
SELECT * FROM books ORDER BY readdate DESC; -- "newest"
SELECT * FROM books ORDER BY recomendationratio DESC; -- "best"
-- Edycja — parametry pozycyjne chronią przed SQL injection
UPDATE books SET description = $1, notes = $2 WHERE id = $3;
03Routing
Lista wszystkich książek —
SELECT * FROM books, formatowanie dat, render index.ejsSortowanie — body
sortType (title/newest/best) → SELECT z ORDER BY → render index.ejsWidok szczegółów — body
bookId → SELECT WHERE id → render edit.ejsZapis edycji — UPDATE description i notes → redirect do
/Usunięcie — DELETE WHERE id → redirect do
/04Stack technologiczny
express.static), obsługa żądań i odpowiedzibooks: id, title, isbn, description, notes, recomendationratio, readdatesrc obrazu. Przeglądarka pobiera bezpośredniohandler() i confirmDelete(). Zero frameworków, czysty DOM API05Czego dowodzi ten projekt
SSR vs SPA
Rozumienie różnicy między server-side rendering a client-side SPA — i kiedy prostsze rozwiązanie jest lepsze.
Surowy SQL
Ręczne zapytania z parametrami pozycyjnymi — świadomy wybór bez ORM, pełne rozumienie co trafia do bazy.
POST/redirect/GET
Klasyczny wzorzec webowy przed fetch() i JSON API — fundamenty protokołu HTTP.
Integracja API
Open Library przez ISBN — integracja zewnętrznego źródła bez żadnego kodu backendowego.
DOM bez frameworków
Inline edit przez setAttribute/removeAttribute — JavaScript w najprostszej formie.
Punkt startowy
Ten projekt poprzedza całe portfolio webowe — od 117 linii SSR do FastAPI, pgvector i OpenAI Agents.
Zobacz kod na GitHubie
117 linii backendu, dwa szablony EJS i jeden plik CSS — cały projekt w zasięgu wzroku.
Zobacz kod na GitHub