Link do aplikacji: https://ti.matra.cc logowanie: admin admin123
Link do repozytorium: https://github.com/fmatrac/home-assistant-api
Aplikacja do zarządzania domem i życiem osobistym napisana w języku Go z wbudowanym interfejsem webowym. System umożliwia zarządzanie kalendarzem wydarzeń, przypomnieniami, produktami, listami zakupów oraz stanami magazynowymi.
Uwaga: Cała inicjalizacja bazy danych (schemat, tabele, typy) znajduje się w folderze
migrations/.
System obsługuje następujące metody wprowadzania danych:
Podstawowym sposobem wprowadzania danych jest interfejs webowy aplikacji. Użytkownik może ręcznie dodawać, edytować i usuwać dane poprzez formularze modalne dostępne w każdej sekcji aplikacji:
- Wydarzenia kalendarzowe - formularze z polami: tytuł, opis, priorytet, data rozpoczęcia/zakończenia, miejsce
- Przypomnienia - formularze z polami: tytuł, opis, status, data uruchomienia, powiązanie z wydarzeniem
- Produkty - formularze z polami: nazwa, kategoria, ulubiony, link do zakupu
- Listy zakupów - formularze z polami: nazwa, status listy
- Pozycje list zakupów - formularze z polami: produkt, ilość, notatka
- Stany magazynowe - formularze z polami: produkt, stan (ok/mało/brak)
System udostępnia REST API umożliwiające automatyczne wprowadzanie danych przez zewnętrzne aplikacje lub skrypty:
# Przykład dodania produktu przez API
curl -X POST http://localhost:8000/api/produkty \
-H "Content-Type: application/json" \
-d '{"nazwa": "Mleko", "kategoria": "Nabiał", "ulubiony": true}'Dane można importować bezpośrednio do bazy PostgreSQL za pomocą skryptów SQL. Przykładowe skrypty znajdują się w katalogu scripts/:
# Import danych z pliku SQL
psql -h localhost -U home_assistant_user -d home_assistant -f scripts/seed_produkty.sql| Metoda | Typ | Opis |
|---|---|---|
| Interfejs webowy | Ręczne | Formularze modalne w przeglądarce |
| REST API | Automatyczne | Żądania HTTP JSON |
| Skrypty SQL | Import | Bezpośredni import do bazy danych |
- Docker i Docker Compose (zalecane)
- Lub: Go 1.24+, PostgreSQL 18+
# Klonowanie repozytorium
git clone <url-repozytorium>
cd home-assistant-api
# Uruchomienie aplikacji
docker compose up -d
# Aplikacja dostępna pod adresem:
# http://localhost:8000# Instalacja zależności
go mod download
# Konfiguracja bazy danych (PostgreSQL)
# Edytuj config/config.yaml z danymi połączenia
# Uruchomienie migracji
goose -dir migrations postgres "postgres://user:pass@localhost:5432/home_assistant" up
# Uruchomienie aplikacji
go run cmd/main.goAplikacja wykorzystuje architekturę warstwową:
┌─────────────────────────────────────────┐
│ Frontend (SPA) │
│ HTML + CSS + Vanilla JavaScript │
├─────────────────────────────────────────┤
│ HTTP Server (api.go) │
│ Routing i middleware │
├─────────────────────────────────────────┤
│ Application (application.go) │
│ Handlery HTTP, logika biznesowa │
├─────────────────────────────────────────┤
│ Repositories (*_repository.go) │
│ Warstwa dostępu do danych │
├─────────────────────────────────────────┤
│ PostgreSQL 18 │
│ Schemat: home_assistant │
└─────────────────────────────────────────┘
| Komponent | Technologia | Wersja |
|---|---|---|
| Backend | Go | 1.24.5 |
| Baza danych | PostgreSQL | 18 |
| Frontend | HTML/CSS/JavaScript | - |
| Logowanie | Logrus | 1.9.3 |
| Konfiguracja | Viper | 1.21.0 |
| Migracje | Goose | - |
| Konteneryzacja | Docker | - |
home-assistant-api/
├── cmd/
│ └── main.go # Punkt wejścia aplikacji
├── pkg/
│ ├── api/
│ │ └── api.go # Serwer HTTP, rejestracja tras
│ ├── application/
│ │ └── application.go # Handlery HTTP, logika biznesowa
│ ├── postgres/
│ │ ├── models.go # Modele danych (struktury Go)
│ │ ├── types.go # Interfejs DB i enumy
│ │ ├── repository_interface.go # Interfejsy repozytoriów
│ │ ├── produkty_repository.go
│ │ ├── listy_zakupow_repository.go
│ │ ├── pozycje_listy_zakupow_repository.go
│ │ ├── stany_magazynowe_repository.go
│ │ ├── historia_stanu_zapasow_repository.go
│ │ ├── przypomnienia_repository.go
│ │ └── wydarzenia_kalendarz_repository.go
│ └── logger/
│ └── logger.go # Wrapper Logrus
├── web/
│ ├── embed.go # Deklaracja embedded FS
│ ├── index.html # Główny interfejs HTML
│ ├── js/
│ │ ├── api.js # Warstwa klienta API
│ │ └── app.js # Logika frontendu
│ └── css/
│ └── style.css # Style CSS
├── config/
│ ├── config.go # Ładowanie konfiguracji
│ └── config.yaml # Plik konfiguracyjny
├── migrations/
│ └── 00001_initialize_db.sql # Schemat bazy danych
├── db-init/
│ └── 01-init-schema.sql # Inicjalizacja schematu (Docker)
├── compose.yaml # Konfiguracja Docker Compose
├── Dockerfile # Multi-stage build
├── go.mod # Zależności Go
└── Makefile # Komendy build/clean
wydarzenia_kalendarz przypomnienia
┌──────────────────┐ ┌──────────────────────┐
│ id (PK) │◄───────┤│ id (PK) │
│ tytul │ │ id_wydarzenia (FK) │
│ opis │ │ tytul │
│ priorytet │ │ opis │
│ data_startu │ │ status │
│ data_zakonczenia │ │ nastepne_uruchomienie│
│ miejsce │ │ utworzono │
│ utworzono │ └──────────────────────┘
└──────────────────┘
produkty listy_zakupow
┌──────────────────┐ ┌──────────────────┐
│ id (PK) │ │ id (PK) │
│ nazwa │ │ nazwa │
│ kategoria │ │ status │
│ ulubiony │ │ utworzono │
│ link_do_kupna │ └────────┬─────────┘
│ utworzono │ │
└────────┬─────────┘ │
│ │
│ pozycje_listy_zakupow │
│ ┌──────────────────────┐ │
└──►│ id (PK) │◄┘
│ id_listy_zakupow (FK)│
│ id_produktu (FK) │
│ ilosc │
│ notatka │
│ czy_kupione │
└──────────────────────┘
produkty stany_magazynowe
┌──────────────────┐ ┌─────────────────────┐
│ id (PK) │◄──────┤│ id (PK) │
└──────────────────┘ │ id_produktu (FK) │
│ │ stan │
│ │ ostatnio_sprawdzono │
│ └─────────────────────┘
│
│ historia_stanu_zapasow
│ ┌──────────────────┐
└─►│ id (PK) │
│ id_produktu (FK) │
│ stan │
│ data_zmiany │
│ notatka │
└──────────────────┘
-- Priorytet wydarzenia
priorytet: 'maly', 'sredni', 'duzy'
-- Status przypomnienia
status_przypomnienia: 'aktywne', 'zrealizowane', 'zapauzowane'
-- Status listy zakupów
status_listy_zakupow: 'otwarta', 'zamknieta'
-- Stan zapasów
stan_zapasow: 'ok', 'malo', 'brak'Serwer nasłuchuje na porcie 8000 (konfigurowalny w config.yaml).
| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /health |
Sprawdzenie stanu aplikacji |
Odpowiedź: {"status": "OK"}
| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/wydarzenia |
Pobierz wszystkie wydarzenia |
| GET | /api/wydarzenia/get?id={id} |
Pobierz pojedyncze wydarzenie |
| POST | /api/wydarzenia |
Utwórz wydarzenie |
| PUT | /api/wydarzenia?id={id} |
Aktualizuj wydarzenie |
| DELETE | /api/wydarzenia?id={id} |
Usuń wydarzenie |
Przykładowe body (POST/PUT):
{
"tytul": "Spotkanie",
"opis": "Opis spotkania",
"priorytet": "sredni",
"data_startu": "2025-01-15T10:00:00Z",
"data_zakonczenia": "2025-01-15T11:00:00Z",
"miejsce": "Biuro"
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/przypomnienia |
Pobierz wszystkie przypomnienia |
| GET | /api/przypomnienia?id_wydarzenia={id} |
Filtruj po wydarzeniu |
| GET | /api/przypomnienia/get?id={id} |
Pobierz pojedyncze przypomnienie |
| POST | /api/przypomnienia |
Utwórz przypomnienie |
| PUT | /api/przypomnienia?id={id} |
Aktualizuj przypomnienie |
| DELETE | /api/przypomnienia?id={id} |
Usuń przypomnienie |
Przykładowe body (POST/PUT):
{
"tytul": "Pamiętaj o spotkaniu",
"opis": "Przypomnienie",
"status": "aktywne",
"nastepne_uruchomienie": "2025-01-15T09:00:00Z",
"id_wydarzenia": 1
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/produkty |
Pobierz wszystkie produkty |
| GET | /api/produkty?kategoria={nazwa} |
Filtruj po kategorii |
| GET | /api/produkty/ulubione |
Pobierz ulubione produkty |
| GET | /api/produkty/get?id={id} |
Pobierz pojedynczy produkt |
| POST | /api/produkty |
Utwórz produkt |
| PUT | /api/produkty?id={id} |
Aktualizuj produkt |
| DELETE | /api/produkty?id={id} |
Usuń produkt |
Przykładowe body (POST/PUT):
{
"nazwa": "Mleko",
"kategoria": "Nabiał",
"ulubiony": true,
"link_do_kupna": "https://sklep.pl/mleko"
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/listy-zakupow |
Pobierz wszystkie listy |
| GET | /api/listy-zakupow?status={status} |
Filtruj po statusie |
| GET | /api/listy-zakupow/get?id={id} |
Pobierz pojedynczą listę |
| POST | /api/listy-zakupow |
Utwórz listę |
| PUT | /api/listy-zakupow?id={id} |
Aktualizuj listę |
| DELETE | /api/listy-zakupow?id={id} |
Usuń listę |
Przykładowe body (POST/PUT):
{
"nazwa": "Zakupy tygodniowe",
"status": "otwarta"
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/pozycje-listy?id_listy={id} |
Pobierz pozycje listy |
| GET | /api/pozycje-listy/get?id={id} |
Pobierz pojedynczą pozycję |
| POST | /api/pozycje-listy |
Dodaj pozycję do listy |
| PUT | /api/pozycje-listy?id={id} |
Aktualizuj pozycję |
| DELETE | /api/pozycje-listy?id={id} |
Usuń pozycję |
| POST | /api/pozycje-listy/kupione?id={id} |
Oznacz jako kupione |
Przykładowe body (POST/PUT):
{
"id_listy_zakupow": 1,
"id_produktu": 5,
"ilosc": 2,
"notatka": "Bio"
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/stany-magazynowe |
Pobierz wszystkie stany |
| GET | /api/stany-magazynowe?stan={stan} |
Filtruj po stanie |
| GET | /api/stany-magazynowe/get?id={id} |
Pobierz pojedynczy stan |
| POST | /api/stany-magazynowe |
Utwórz stan |
| PUT | /api/stany-magazynowe?id={id} |
Aktualizuj stan |
| DELETE | /api/stany-magazynowe?id={id} |
Usuń stan |
Przykładowe body (POST/PUT):
{
"id_produktu": 5,
"stan": "malo"
}| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/historia-zapasow |
Pobierz całą historię |
| GET | /api/historia-zapasow?id_produktu={id} |
Historia produktu |
| POST | /api/historia-zapasow |
Dodaj wpis historii |
Każda encja posiada własny interfejs repozytorium i implementację:
// Interfejs repozytorium (repository_interface.go)
type ProduktyRepository interface {
GetAll(ctx context.Context) ([]Produkt, error)
GetByID(ctx context.Context, id int) (*Produkt, error)
GetByKategoria(ctx context.Context, kategoria string) ([]Produkt, error)
GetUlubione(ctx context.Context) ([]Produkt, error)
Create(ctx context.Context, p *Produkt) error
Update(ctx context.Context, p *Produkt) error
Delete(ctx context.Context, id int) error
}
// Implementacja (produkty_repository.go)
type produktyRepository struct {
db DB
}
func NewProduktyRepository(db DB) ProduktyRepository {
return &produktyRepository{db: db}
}Repozytoria są wstrzykiwane do struktury Application:
// application.go
type Application struct {
wydarzenia postgres.WydarzeniaKalendarzRepository
przypomnienia postgres.PrzypomieniaRepository
produkty postgres.ProduktyRepository
listyZakupow postgres.ListyZakupowRepository
pozycjeListy postgres.PozycjeListyZakupowRepository
stanyMagazynowe postgres.StanyMagazynoweRepository
historiaZapasow postgres.HistoriaStanuZapasowRepository
}Frontend jest wbudowany w binarkę Go:
// web/embed.go
//go:embed index.html css js
var WebFS embed.FSPlik config/config.yaml:
server:
port: 8000 # Port serwera HTTP
postgres:
conn: "postgres://home_assistant_user:home_assistant_password@db:5432/home_assistant?sslmode=disable"
logging:
level: "info" # Poziom logowania: debug, info, warn, error