diff --git a/.env.example b/.env.example index 8249555..44465e8 100644 --- a/.env.example +++ b/.env.example @@ -3,7 +3,7 @@ PG_HOST=pg.localnet PG_PORT=5432 PG_USER=album PG_PASSWORD=change_me -PG_DATABASE=shared_album +PG_DATABASE=galo PG_SSLMODE=disable # Metadata backend: sqlite (default, embedded single instance) or postgres diff --git a/Makefile b/Makefile index 28e72cc..2e8ee55 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,7 @@ -.PHONY: build frontend backend run migrate reconcile reconcile-delete tidy test clean +.PHONY: build build-release frontend backend run migrate reconcile reconcile-delete tidy test clean + +# Release version stamped into the binary (-X main.version). Override with VERSION=... +VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev) frontend: cd frontend && npm ci && npm run build @@ -10,12 +13,27 @@ backend: # -tags nodynamic forces gen2brain/webp to use its pure-Go transpiled path # (no purego/dlopen), keeping the binary fully static. cd backend && CGO_ENABLED=0 go build -tags nodynamic -trimpath -ldflags="-s -w" \ - -o ../bin/shared-album ./cmd/server + -o ../bin/galo ./cmd/server build: frontend backend +# Release build: full static, stripped and (if available) UPX-compressed binary +# with the version embedded. Produces bin/galo and a copy at bin/galo-$(VERSION). +build-release: frontend + mkdir -p bin + cd backend && CGO_ENABLED=0 go build -tags nodynamic -trimpath \ + -ldflags="-s -w -X main.version=$(VERSION)" -o ../bin/galo ./cmd/server + strip --strip-all bin/galo + @if command -v upx >/dev/null 2>&1; then \ + upx --best --quiet bin/galo && echo "upx: bin/galo compressed"; \ + else \ + echo "upx not found - skipping compression (install upx-ucl to enable)"; \ + fi + cp bin/galo bin/galo-$(VERSION) + @echo "release: bin/galo-$(VERSION)" + run: backend - cd backend && ../bin/shared-album + ./bin/galo migrate: cd backend && go run ./cmd/migrate diff --git a/README.md b/README.md index b28ad37..a0ba69d 100644 --- a/README.md +++ b/README.md @@ -47,14 +47,14 @@ cp .env.example .env ## Сборка ```bash -make build # frontend -> backend/static -> go:embed -> bin/shared-album +make build # frontend -> backend/static -> go:embed -> bin/galo ``` Отдельные шаги: ```bash make frontend # npm ci && npm run build, копирует статику в backend/static -make backend # CGO_ENABLED=0 go build -tags nodynamic -o bin/shared-album +make backend # CGO_ENABLED=0 go build -tags nodynamic -o bin/galo ``` > `-tags nodynamic` обязателен: он заставляет `gen2brain/webp` использовать @@ -64,7 +64,7 @@ make backend # CGO_ENABLED=0 go build -tags nodynamic -o bin/shared-album Проверка: ```bash -file bin/shared-album # => statically linked +file bin/galo # => statically linked ``` ## Миграции @@ -79,9 +79,9 @@ make migrate # go run ./cmd/migrate — применяет up-миграци ## Локальный запуск ```bash -make run # соберёт backend и запустит ./bin/shared-album +make run # соберёт backend и запустит ./bin/galo # или напрямую: -./bin/shared-album +./bin/galo ``` Сервер слушает `HTTP_ADDR` (по умолчанию `:8080`). Health-check: @@ -126,20 +126,20 @@ go run ./cmd/reconcile --delete # удалить сироты старше --m 2. Создайте пользователя и каталог: ```bash - sudo useradd --system --home /opt/shared-album album - sudo mkdir -p /opt/shared-album - sudo cp bin/shared-album /opt/shared-album/ - sudo cp .env /opt/shared-album/.env - sudo chown -R album:album /opt/shared-album + sudo useradd --system --home /opt/galo album + sudo mkdir -p /opt/galo + sudo cp bin/galo /opt/galo/ + sudo cp .env /opt/galo/.env + sudo chown -R album:album /opt/galo ``` 3. Установите unit: ```bash - sudo cp deploy/shared-album.service /etc/systemd/system/ + sudo cp deploy/galo.service /etc/systemd/system/ sudo systemctl daemon-reload - sudo systemctl enable --now shared-album - sudo journalctl -u shared-album -f + sudo systemctl enable --now galo + sudo journalctl -u galo -f ``` ## nginx (опционально) diff --git a/backend/cmd/backfill-exif/main.go b/backend/cmd/backfill-exif/main.go index 3a6137a..9b47da1 100644 --- a/backend/cmd/backfill-exif/main.go +++ b/backend/cmd/backfill-exif/main.go @@ -7,11 +7,11 @@ import ( "os" "strings" - "shared-album/internal/config" - "shared-album/internal/db" - "shared-album/internal/settings" - "shared-album/internal/storage" - "shared-album/internal/store" + "galo/internal/config" + "galo/internal/db" + "galo/internal/settings" + "galo/internal/storage" + "galo/internal/store" ) func main() { diff --git a/backend/cmd/migrate/main.go b/backend/cmd/migrate/main.go index 7576c91..94808e1 100644 --- a/backend/cmd/migrate/main.go +++ b/backend/cmd/migrate/main.go @@ -5,9 +5,9 @@ import ( "log/slog" "os" - assets "shared-album" - "shared-album/internal/config" - "shared-album/internal/db" + assets "galo" + "galo/internal/config" + "galo/internal/db" ) func main() { diff --git a/backend/cmd/reconcile/main.go b/backend/cmd/reconcile/main.go index 04897ab..8ce9dfd 100644 --- a/backend/cmd/reconcile/main.go +++ b/backend/cmd/reconcile/main.go @@ -14,13 +14,13 @@ import ( "strings" "time" - assets "shared-album" - "shared-album/internal/config" - "shared-album/internal/db" - "shared-album/internal/reconcile" - "shared-album/internal/settings" - "shared-album/internal/storage" - "shared-album/internal/store" + assets "galo" + "galo/internal/config" + "galo/internal/db" + "galo/internal/reconcile" + "galo/internal/settings" + "galo/internal/storage" + "galo/internal/store" ) const objectPrefix = "objects/" diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 0a72ec5..efedea3 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -13,23 +13,27 @@ import ( "syscall" "time" - assets "shared-album" - "shared-album/internal/app" - "shared-album/internal/auth" - "shared-album/internal/config" - "shared-album/internal/db" - "shared-album/internal/settings" - "shared-album/internal/sse" - "shared-album/internal/storage" - "shared-album/internal/store" + assets "galo" + "galo/internal/app" + "galo/internal/auth" + "galo/internal/config" + "galo/internal/db" + "galo/internal/settings" + "galo/internal/sse" + "galo/internal/storage" + "galo/internal/store" ) +// version is set at build time via -ldflags "-X main.version=..." +var version = "dev" + func main() { loadDotEnv(".env") loadDotEnv("../.env") logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) slog.SetDefault(logger) + slog.Info("starting galo", "version", version) cfg, err := config.Load() if err != nil { diff --git a/backend/go.mod b/backend/go.mod index 4ca3177..d07f934 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,4 +1,4 @@ -module shared-album +module galo go 1.26.1 diff --git a/backend/internal/albums/handlers.go b/backend/internal/albums/handlers.go index 2b00705..f7cc41b 100644 --- a/backend/internal/albums/handlers.go +++ b/backend/internal/albums/handlers.go @@ -5,8 +5,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/albums/repository.go b/backend/internal/albums/repository.go index e22c98c..3b1ee18 100644 --- a/backend/internal/albums/repository.go +++ b/backend/internal/albums/repository.go @@ -3,7 +3,7 @@ package albums import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the albums domain. diff --git a/backend/internal/albums/service.go b/backend/internal/albums/service.go index 57ac51b..46883d0 100644 --- a/backend/internal/albums/service.go +++ b/backend/internal/albums/service.go @@ -5,12 +5,12 @@ import ( "errors" "strings" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/roles" - "shared-album/internal/sse" - "shared-album/internal/storage" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/roles" + "galo/internal/sse" + "galo/internal/storage" ) type MemberLookup interface { diff --git a/backend/internal/albums/sqlite_store.go b/backend/internal/albums/sqlite_store.go index c8bf624..22d1654 100644 --- a/backend/internal/albums/sqlite_store.go +++ b/backend/internal/albums/sqlite_store.go @@ -6,8 +6,8 @@ import ( "errors" "time" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/albums/store.go b/backend/internal/albums/store.go index 2ceaf5c..40539b2 100644 --- a/backend/internal/albums/store.go +++ b/backend/internal/albums/store.go @@ -7,8 +7,8 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/httpx" - "shared-album/internal/models" + "galo/internal/httpx" + "galo/internal/models" ) var ErrNotFound = errors.New("album not found") diff --git a/backend/internal/app/app.go b/backend/internal/app/app.go index b775fc1..3379c4d 100644 --- a/backend/internal/app/app.go +++ b/backend/internal/app/app.go @@ -10,19 +10,19 @@ import ( "github.com/gin-gonic/gin" - assets "shared-album" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/config" - "shared-album/internal/httpx" - "shared-album/internal/members" - "shared-album/internal/notifications" - "shared-album/internal/photos" - "shared-album/internal/sharelinks" - "shared-album/internal/social" - "shared-album/internal/sse" - "shared-album/internal/storage" - "shared-album/internal/store" + assets "galo" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/config" + "galo/internal/httpx" + "galo/internal/members" + "galo/internal/notifications" + "galo/internal/photos" + "galo/internal/sharelinks" + "galo/internal/social" + "galo/internal/sse" + "galo/internal/storage" + "galo/internal/store" ) type Server struct { diff --git a/backend/internal/app/health_test.go b/backend/internal/app/health_test.go index 4b934a5..b9588e4 100644 --- a/backend/internal/app/health_test.go +++ b/backend/internal/app/health_test.go @@ -10,8 +10,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/config" - "shared-album/internal/storage" + "galo/internal/config" + "galo/internal/storage" ) func mustSigner(t *testing.T) *storage.Signer { diff --git a/backend/internal/app/objects_test.go b/backend/internal/app/objects_test.go index fb94e8f..4455452 100644 --- a/backend/internal/app/objects_test.go +++ b/backend/internal/app/objects_test.go @@ -12,11 +12,11 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/config" - "shared-album/internal/sse" - "shared-album/internal/storage" - "shared-album/internal/store" + "galo/internal/auth" + "galo/internal/config" + "galo/internal/sse" + "galo/internal/storage" + "galo/internal/store" ) func newTestServerWithFS(t *testing.T) (*storage.FS, *gin.Engine) { diff --git a/backend/internal/app/share_flow_test.go b/backend/internal/app/share_flow_test.go index 8548ad9..5f17255 100644 --- a/backend/internal/app/share_flow_test.go +++ b/backend/internal/app/share_flow_test.go @@ -18,16 +18,16 @@ import ( "github.com/gin-gonic/gin" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/config" - "shared-album/internal/members" - "shared-album/internal/models" - "shared-album/internal/photos" - "shared-album/internal/sharelinks" - "shared-album/internal/sse" - "shared-album/internal/storage" - "shared-album/internal/store" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/config" + "galo/internal/members" + "galo/internal/models" + "galo/internal/photos" + "galo/internal/sharelinks" + "galo/internal/sse" + "galo/internal/storage" + "galo/internal/store" ) func integrationPool(t *testing.T) *pgxpool.Pool { diff --git a/backend/internal/auth/handlers.go b/backend/internal/auth/handlers.go index 352ec41..410704f 100644 --- a/backend/internal/auth/handlers.go +++ b/backend/internal/auth/handlers.go @@ -8,7 +8,7 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/httpx" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/auth/middleware.go b/backend/internal/auth/middleware.go index 8c865cb..066ce99 100644 --- a/backend/internal/auth/middleware.go +++ b/backend/internal/auth/middleware.go @@ -5,7 +5,7 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/httpx" + "galo/internal/httpx" ) const ( diff --git a/backend/internal/auth/repository.go b/backend/internal/auth/repository.go index dcd75bc..5a5820a 100644 --- a/backend/internal/auth/repository.go +++ b/backend/internal/auth/repository.go @@ -3,7 +3,7 @@ package auth import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the auth domain. diff --git a/backend/internal/auth/service.go b/backend/internal/auth/service.go index 0453f79..bcd808d 100644 --- a/backend/internal/auth/service.go +++ b/backend/internal/auth/service.go @@ -6,8 +6,8 @@ import ( "strings" "time" - "shared-album/internal/httpx" - "shared-album/internal/models" + "galo/internal/httpx" + "galo/internal/models" ) type TokenPair struct { diff --git a/backend/internal/auth/sqlite_store.go b/backend/internal/auth/sqlite_store.go index 07b5312..b0022bb 100644 --- a/backend/internal/auth/sqlite_store.go +++ b/backend/internal/auth/sqlite_store.go @@ -7,8 +7,8 @@ import ( "errors" "time" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/auth/store.go b/backend/internal/auth/store.go index 054375c..c82db6d 100644 --- a/backend/internal/auth/store.go +++ b/backend/internal/auth/store.go @@ -8,7 +8,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/models" + "galo/internal/models" ) var ErrNotFound = errors.New("not found") diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index ef51c83..ca15eb9 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -131,7 +131,7 @@ func Load() (*Config, error) { Port: pgPort, User: getEnv("PG_USER", "album"), Password: getEnv("PG_PASSWORD", ""), - Database: getEnv("PG_DATABASE", "shared_album"), + Database: getEnv("PG_DATABASE", "galo"), SSLMode: getEnv("PG_SSLMODE", "disable"), }, S3: S3{ diff --git a/backend/internal/db/migrate_sqlite_test.go b/backend/internal/db/migrate_sqlite_test.go index c6387d9..3c0c48d 100644 --- a/backend/internal/db/migrate_sqlite_test.go +++ b/backend/internal/db/migrate_sqlite_test.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - assets "shared-album" + assets "galo" ) func TestMigrateSQLite(t *testing.T) { diff --git a/backend/internal/e2e/sqlite_test.go b/backend/internal/e2e/sqlite_test.go index 29e9046..91e2c0e 100644 --- a/backend/internal/e2e/sqlite_test.go +++ b/backend/internal/e2e/sqlite_test.go @@ -12,15 +12,15 @@ import ( "testing" "time" - assets "shared-album" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/db" - "shared-album/internal/photos" - "shared-album/internal/settings" - "shared-album/internal/sse" - "shared-album/internal/storage" - "shared-album/internal/store" + assets "galo" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/db" + "galo/internal/photos" + "galo/internal/settings" + "galo/internal/sse" + "galo/internal/storage" + "galo/internal/store" ) func makePNG(t *testing.T) []byte { diff --git a/backend/internal/members/handlers.go b/backend/internal/members/handlers.go index b8c47ac..db1308d 100644 --- a/backend/internal/members/handlers.go +++ b/backend/internal/members/handlers.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/members/repository.go b/backend/internal/members/repository.go index b700c99..69b95ec 100644 --- a/backend/internal/members/repository.go +++ b/backend/internal/members/repository.go @@ -3,7 +3,7 @@ package members import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the members domain. diff --git a/backend/internal/members/service.go b/backend/internal/members/service.go index 361725f..5d4cb92 100644 --- a/backend/internal/members/service.go +++ b/backend/internal/members/service.go @@ -5,11 +5,11 @@ import ( "errors" "time" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/roles" - "shared-album/internal/sse" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/roles" + "galo/internal/sse" ) type AlbumReader interface { diff --git a/backend/internal/members/sqlite_store.go b/backend/internal/members/sqlite_store.go index 76771df..76e9709 100644 --- a/backend/internal/members/sqlite_store.go +++ b/backend/internal/members/sqlite_store.go @@ -5,8 +5,8 @@ import ( "database/sql" "errors" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/members/store.go b/backend/internal/members/store.go index 2786476..970f06c 100644 --- a/backend/internal/members/store.go +++ b/backend/internal/members/store.go @@ -7,7 +7,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/models" + "galo/internal/models" ) var ErrNotFound = errors.New("not found") diff --git a/backend/internal/notifications/handlers.go b/backend/internal/notifications/handlers.go index 4a6c547..6021536 100644 --- a/backend/internal/notifications/handlers.go +++ b/backend/internal/notifications/handlers.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/notifications/repository.go b/backend/internal/notifications/repository.go index c69d9db..e4889ca 100644 --- a/backend/internal/notifications/repository.go +++ b/backend/internal/notifications/repository.go @@ -3,7 +3,7 @@ package notifications import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the notifications domain. diff --git a/backend/internal/notifications/service.go b/backend/internal/notifications/service.go index 1abf9b2..54af797 100644 --- a/backend/internal/notifications/service.go +++ b/backend/internal/notifications/service.go @@ -3,10 +3,10 @@ package notifications import ( "context" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/sse" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/sse" ) type Service struct { diff --git a/backend/internal/notifications/sqlite_store.go b/backend/internal/notifications/sqlite_store.go index 061bdb9..4798bfb 100644 --- a/backend/internal/notifications/sqlite_store.go +++ b/backend/internal/notifications/sqlite_store.go @@ -7,8 +7,8 @@ import ( "errors" "time" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/notifications/store.go b/backend/internal/notifications/store.go index 9de08b1..e66bebc 100644 --- a/backend/internal/notifications/store.go +++ b/backend/internal/notifications/store.go @@ -8,7 +8,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/models" + "galo/internal/models" ) var ErrNotFound = errors.New("not found") diff --git a/backend/internal/photos/handlers.go b/backend/internal/photos/handlers.go index c207078..3a75acc 100644 --- a/backend/internal/photos/handlers.go +++ b/backend/internal/photos/handlers.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) const maxUploadSize = 100 << 20 diff --git a/backend/internal/photos/helpers_test.go b/backend/internal/photos/helpers_test.go index 0659663..f68c825 100644 --- a/backend/internal/photos/helpers_test.go +++ b/backend/internal/photos/helpers_test.go @@ -12,12 +12,12 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/auth" - "shared-album/internal/config" - "shared-album/internal/models" - "shared-album/internal/roles" - "shared-album/internal/sse" - "shared-album/internal/storage" + "galo/internal/auth" + "galo/internal/config" + "galo/internal/models" + "galo/internal/roles" + "galo/internal/sse" + "galo/internal/storage" ) func testPool(t *testing.T) *pgxpool.Pool { diff --git a/backend/internal/photos/objects_test.go b/backend/internal/photos/objects_test.go index 18fbf78..2d78409 100644 --- a/backend/internal/photos/objects_test.go +++ b/backend/internal/photos/objects_test.go @@ -8,7 +8,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/auth" + "galo/internal/auth" ) func TestObjectStateTransitions(t *testing.T) { diff --git a/backend/internal/photos/repository.go b/backend/internal/photos/repository.go index 48d56e2..f352dc2 100644 --- a/backend/internal/photos/repository.go +++ b/backend/internal/photos/repository.go @@ -4,7 +4,7 @@ import ( "context" "time" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the photos domain, including the diff --git a/backend/internal/photos/service.go b/backend/internal/photos/service.go index d5191d8..c128652 100644 --- a/backend/internal/photos/service.go +++ b/backend/internal/photos/service.go @@ -9,12 +9,12 @@ import ( "strings" "time" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/roles" - "shared-album/internal/sse" - "shared-album/internal/storage" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/roles" + "galo/internal/sse" + "galo/internal/storage" ) type AlbumAccess interface { diff --git a/backend/internal/photos/sqlite_helpers.go b/backend/internal/photos/sqlite_helpers.go index 02190fc..3797ffb 100644 --- a/backend/internal/photos/sqlite_helpers.go +++ b/backend/internal/photos/sqlite_helpers.go @@ -3,7 +3,7 @@ package photos import ( "time" - "shared-album/internal/sqliteutil" + "galo/internal/sqliteutil" ) func nullIfEmpty(s string) any { diff --git a/backend/internal/photos/sqlite_objects.go b/backend/internal/photos/sqlite_objects.go index 54b1722..9fa6da3 100644 --- a/backend/internal/photos/sqlite_objects.go +++ b/backend/internal/photos/sqlite_objects.go @@ -6,7 +6,7 @@ import ( "errors" "time" - "shared-album/internal/sqliteutil" + "galo/internal/sqliteutil" ) // CreateObject inserts a new object row in the pending state. diff --git a/backend/internal/photos/sqlite_store.go b/backend/internal/photos/sqlite_store.go index 1af97bd..c943fe1 100644 --- a/backend/internal/photos/sqlite_store.go +++ b/backend/internal/photos/sqlite_store.go @@ -7,9 +7,9 @@ import ( "errors" "strings" - "shared-album/internal/auth" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/auth" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/photos/store.go b/backend/internal/photos/store.go index ff59950..66ff25b 100644 --- a/backend/internal/photos/store.go +++ b/backend/internal/photos/store.go @@ -11,8 +11,8 @@ import ( "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/auth" - "shared-album/internal/models" + "galo/internal/auth" + "galo/internal/models" ) var ErrNotFound = errors.New("photo not found") diff --git a/backend/internal/photos/worker.go b/backend/internal/photos/worker.go index 9f1352d..80d76b0 100644 --- a/backend/internal/photos/worker.go +++ b/backend/internal/photos/worker.go @@ -7,7 +7,7 @@ import ( "log/slog" "time" - "shared-album/internal/auth" + "galo/internal/auth" ) const maxVariantAttempts = 5 diff --git a/backend/internal/photos/worker_test.go b/backend/internal/photos/worker_test.go index 3ba70e7..5b7f165 100644 --- a/backend/internal/photos/worker_test.go +++ b/backend/internal/photos/worker_test.go @@ -7,7 +7,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/storage" + "galo/internal/storage" ) func TestWorkerGeneratesVariantsAndCollects(t *testing.T) { diff --git a/backend/internal/reconcile/reconcile.go b/backend/internal/reconcile/reconcile.go index 2782edf..56f3bc6 100644 --- a/backend/internal/reconcile/reconcile.go +++ b/backend/internal/reconcile/reconcile.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "shared-album/internal/storage" + "galo/internal/storage" ) // Result holds the two kinds of divergence between storage and the journal. diff --git a/backend/internal/reconcile/reconcile_test.go b/backend/internal/reconcile/reconcile_test.go index a06c9b8..b9c9fe5 100644 --- a/backend/internal/reconcile/reconcile_test.go +++ b/backend/internal/reconcile/reconcile_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "shared-album/internal/storage" + "galo/internal/storage" ) func TestClassify(t *testing.T) { diff --git a/backend/internal/repo/contract/contract.go b/backend/internal/repo/contract/contract.go index c1fa1c5..25cd9b8 100644 --- a/backend/internal/repo/contract/contract.go +++ b/backend/internal/repo/contract/contract.go @@ -9,15 +9,15 @@ import ( "testing" "time" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/members" - "shared-album/internal/models" - "shared-album/internal/notifications" - "shared-album/internal/photos" - "shared-album/internal/settings" - "shared-album/internal/sharelinks" - "shared-album/internal/social" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/members" + "galo/internal/models" + "galo/internal/notifications" + "galo/internal/photos" + "galo/internal/settings" + "galo/internal/sharelinks" + "galo/internal/social" ) // Repos bundles one repository per domain plus a Reset hook that clears all diff --git a/backend/internal/repo/contract/postgres_test.go b/backend/internal/repo/contract/postgres_test.go index c8df098..652c2fa 100644 --- a/backend/internal/repo/contract/postgres_test.go +++ b/backend/internal/repo/contract/postgres_test.go @@ -10,16 +10,16 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - assets "shared-album" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/db" - "shared-album/internal/members" - "shared-album/internal/notifications" - "shared-album/internal/photos" - "shared-album/internal/settings" - "shared-album/internal/sharelinks" - "shared-album/internal/social" + assets "galo" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/db" + "galo/internal/members" + "galo/internal/notifications" + "galo/internal/photos" + "galo/internal/settings" + "galo/internal/sharelinks" + "galo/internal/social" ) // TestPostgresContract runs the shared suite against PostgreSQL inside its own diff --git a/backend/internal/repo/contract/sqlite_test.go b/backend/internal/repo/contract/sqlite_test.go index 0b52489..1873d69 100644 --- a/backend/internal/repo/contract/sqlite_test.go +++ b/backend/internal/repo/contract/sqlite_test.go @@ -6,16 +6,16 @@ import ( "path/filepath" "testing" - assets "shared-album" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/db" - "shared-album/internal/members" - "shared-album/internal/notifications" - "shared-album/internal/photos" - "shared-album/internal/settings" - "shared-album/internal/sharelinks" - "shared-album/internal/social" + assets "galo" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/db" + "galo/internal/members" + "galo/internal/notifications" + "galo/internal/photos" + "galo/internal/settings" + "galo/internal/sharelinks" + "galo/internal/social" ) func TestSQLiteContract(t *testing.T) { diff --git a/backend/internal/repo/repo_test.go b/backend/internal/repo/repo_test.go index df56c88..eafb44a 100644 --- a/backend/internal/repo/repo_test.go +++ b/backend/internal/repo/repo_test.go @@ -8,12 +8,12 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/members" - "shared-album/internal/models" - "shared-album/internal/photos" - "shared-album/internal/sharelinks" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/members" + "galo/internal/models" + "galo/internal/photos" + "galo/internal/sharelinks" ) func testPool(t *testing.T) *pgxpool.Pool { diff --git a/backend/internal/settings/sqlite_store.go b/backend/internal/settings/sqlite_store.go index 61970d6..253658c 100644 --- a/backend/internal/settings/sqlite_store.go +++ b/backend/internal/settings/sqlite_store.go @@ -7,7 +7,7 @@ import ( "fmt" "time" - "shared-album/internal/sqliteutil" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/sharelinks/handlers.go b/backend/internal/sharelinks/handlers.go index 7abfce4..7ddeda0 100644 --- a/backend/internal/sharelinks/handlers.go +++ b/backend/internal/sharelinks/handlers.go @@ -6,8 +6,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/sharelinks/repository.go b/backend/internal/sharelinks/repository.go index 54b7702..a752d52 100644 --- a/backend/internal/sharelinks/repository.go +++ b/backend/internal/sharelinks/repository.go @@ -3,7 +3,7 @@ package sharelinks import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the share-links domain. diff --git a/backend/internal/sharelinks/service.go b/backend/internal/sharelinks/service.go index 13db847..7c00645 100644 --- a/backend/internal/sharelinks/service.go +++ b/backend/internal/sharelinks/service.go @@ -5,10 +5,10 @@ import ( "errors" "time" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/roles" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/roles" ) type AlbumAccess interface { diff --git a/backend/internal/sharelinks/sqlite_store.go b/backend/internal/sharelinks/sqlite_store.go index 15a04df..7c88262 100644 --- a/backend/internal/sharelinks/sqlite_store.go +++ b/backend/internal/sharelinks/sqlite_store.go @@ -6,8 +6,8 @@ import ( "errors" "time" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/sharelinks/store.go b/backend/internal/sharelinks/store.go index 244d5ee..b802e78 100644 --- a/backend/internal/sharelinks/store.go +++ b/backend/internal/sharelinks/store.go @@ -7,7 +7,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/models" + "galo/internal/models" ) var ErrNotFound = errors.New("not found") diff --git a/backend/internal/social/handlers.go b/backend/internal/social/handlers.go index 8520202..711d0fc 100644 --- a/backend/internal/social/handlers.go +++ b/backend/internal/social/handlers.go @@ -5,8 +5,8 @@ import ( "github.com/gin-gonic/gin" - "shared-album/internal/auth" - "shared-album/internal/httpx" + "galo/internal/auth" + "galo/internal/httpx" ) type Handler struct { diff --git a/backend/internal/social/repository.go b/backend/internal/social/repository.go index d1d48f7..853212f 100644 --- a/backend/internal/social/repository.go +++ b/backend/internal/social/repository.go @@ -3,7 +3,7 @@ package social import ( "context" - "shared-album/internal/models" + "galo/internal/models" ) // Repository is the persistence contract for the social domain. diff --git a/backend/internal/social/service.go b/backend/internal/social/service.go index 3e7a0cd..0d54e94 100644 --- a/backend/internal/social/service.go +++ b/backend/internal/social/service.go @@ -5,11 +5,11 @@ import ( "errors" "strings" - "shared-album/internal/auth" - "shared-album/internal/httpx" - "shared-album/internal/models" - "shared-album/internal/roles" - "shared-album/internal/sse" + "galo/internal/auth" + "galo/internal/httpx" + "galo/internal/models" + "galo/internal/roles" + "galo/internal/sse" ) type AlbumAccess interface { diff --git a/backend/internal/social/sqlite_store.go b/backend/internal/social/sqlite_store.go index 26ba01f..5d40f01 100644 --- a/backend/internal/social/sqlite_store.go +++ b/backend/internal/social/sqlite_store.go @@ -5,8 +5,8 @@ import ( "database/sql" "errors" - "shared-album/internal/models" - "shared-album/internal/sqliteutil" + "galo/internal/models" + "galo/internal/sqliteutil" ) // SQLiteStore is the SQLite implementation of Repository. diff --git a/backend/internal/social/store.go b/backend/internal/social/store.go index a2852bb..c43ee4d 100644 --- a/backend/internal/social/store.go +++ b/backend/internal/social/store.go @@ -7,7 +7,7 @@ import ( "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/models" + "galo/internal/models" ) var ErrNotFound = errors.New("not found") diff --git a/backend/internal/storage/s3_test.go b/backend/internal/storage/s3_test.go index 6a7f777..95812db 100644 --- a/backend/internal/storage/s3_test.go +++ b/backend/internal/storage/s3_test.go @@ -13,7 +13,7 @@ import ( "testing" "time" - "shared-album/internal/config" + "galo/internal/config" ) func newTestS3(t *testing.T) (*S3, *Signer) { diff --git a/backend/internal/storage/storage.go b/backend/internal/storage/storage.go index 7303f7c..6e938bc 100644 --- a/backend/internal/storage/storage.go +++ b/backend/internal/storage/storage.go @@ -17,7 +17,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/aws/smithy-go" - "shared-album/internal/config" + "galo/internal/config" ) // ErrSignedURLInvalid is returned when an app-served object URL has a missing, diff --git a/backend/internal/store/store.go b/backend/internal/store/store.go index 54eda95..a5b694f 100644 --- a/backend/internal/store/store.go +++ b/backend/internal/store/store.go @@ -8,14 +8,14 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - "shared-album/internal/albums" - "shared-album/internal/auth" - "shared-album/internal/members" - "shared-album/internal/notifications" - "shared-album/internal/photos" - "shared-album/internal/settings" - "shared-album/internal/sharelinks" - "shared-album/internal/social" + "galo/internal/albums" + "galo/internal/auth" + "galo/internal/members" + "galo/internal/notifications" + "galo/internal/photos" + "galo/internal/settings" + "galo/internal/sharelinks" + "galo/internal/social" ) // Repos bundles one repository per domain. diff --git a/backend/internal/store/store_test.go b/backend/internal/store/store_test.go index 6961d97..7726a07 100644 --- a/backend/internal/store/store_test.go +++ b/backend/internal/store/store_test.go @@ -9,8 +9,8 @@ import ( "github.com/jackc/pgx/v5/pgxpool" - assets "shared-album" - "shared-album/internal/db" + assets "galo" + "galo/internal/db" ) func assertComplete(t *testing.T, r Repos) { diff --git a/deploy/shared-album.service b/deploy/galo.service similarity index 60% rename from deploy/shared-album.service rename to deploy/galo.service index 2726c30..f482426 100644 --- a/deploy/shared-album.service +++ b/deploy/galo.service @@ -1,5 +1,5 @@ [Unit] -Description=Shared Album backend +Description=Galo backend After=network-online.target Wants=network-online.target @@ -7,9 +7,9 @@ Wants=network-online.target Type=simple User=album Group=album -WorkingDirectory=/opt/shared-album -EnvironmentFile=/opt/shared-album/.env -ExecStart=/opt/shared-album/shared-album +WorkingDirectory=/opt/galo +EnvironmentFile=/opt/galo/.env +ExecStart=/opt/galo/galo Restart=on-failure RestartSec=5s @@ -18,7 +18,7 @@ NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true -ReadWritePaths=/opt/shared-album +ReadWritePaths=/opt/galo [Install] WantedBy=multi-user.target diff --git a/deploy/nginx-sse.conf b/deploy/nginx-sse.conf index 19e08ed..34b31a5 100644 --- a/deploy/nginx-sse.conf +++ b/deploy/nginx-sse.conf @@ -1,7 +1,7 @@ # Пример nginx-конфигурации перед Go-бэкендом. # Для SSE критично proxy_buffering off, иначе события буферизуются и не доходят. -upstream shared_album { +upstream galo { server 127.0.0.1:8080; } @@ -12,7 +12,7 @@ server { client_max_body_size 60m; location /api/sse/ { - proxy_pass http://shared_album; + proxy_pass http://galo; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering off; # иначе SSE буферизуется @@ -22,7 +22,7 @@ server { } location /api/objects/ { - proxy_pass http://shared_album; + proxy_pass http://galo; proxy_http_version 1.1; proxy_set_header Host $host; proxy_buffering off; # стриминг объектов без буферизации @@ -30,7 +30,7 @@ server { } location / { - proxy_pass http://shared_album; + proxy_pass http://galo; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 409c4db..e8ea332 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,11 +1,11 @@ { - "name": "shared-album-frontend", + "name": "galo-frontend", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "shared-album-frontend", + "name": "galo-frontend", "version": "0.0.1", "devDependencies": { "@sveltejs/adapter-static": "^3.0.6", @@ -1102,6 +1102,72 @@ "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 3967b9f..8978ef4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,5 +1,5 @@ { - "name": "shared-album-frontend", + "name": "galo-frontend", "private": true, "version": "0.0.1", "type": "module", diff --git a/frontend/src/app.html b/frontend/src/app.html index e616e5c..06cf16b 100644 --- a/frontend/src/app.html +++ b/frontend/src/app.html @@ -3,7 +3,9 @@
- + + + + + diff --git a/frontend/src/routes/(public)/+layout.svelte b/frontend/src/routes/(public)/+layout.svelte index a14569d..9e3f3b5 100644 --- a/frontend/src/routes/(public)/+layout.svelte +++ b/frontend/src/routes/(public)/+layout.svelte @@ -1,6 +1,6 @@ @@ -9,7 +9,7 @@