feat: rename service to galo, add halo branding and release build

- rename Go module, binary, systemd unit, PG_DATABASE default, frontend package and docs from shared-album to galo
- add theme-aware halo emblem and favicon (new ui-branding capability)
- add make build-release (versioned, stripped, static binary) and run the binary from the repo root
This commit is contained in:
iu
2026-10-11 11:36:56 +03:00
parent 29c2594a9b
commit 50dff63ece
89 changed files with 696 additions and 254 deletions
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -3,7 +3,7 @@ package albums
import (
"context"
"shared-album/internal/models"
"galo/internal/models"
)
// Repository is the persistence contract for the albums domain.
+6 -6
View File
@@ -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 {
+2 -2
View File
@@ -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.
+2 -2
View File
@@ -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")
+13 -13
View File
@@ -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 {
+2 -2
View File
@@ -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 {
+5 -5
View File
@@ -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) {
+10 -10
View File
@@ -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 {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/gin-gonic/gin"
"shared-album/internal/httpx"
"galo/internal/httpx"
)
type Handler struct {
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"github.com/gin-gonic/gin"
"shared-album/internal/httpx"
"galo/internal/httpx"
)
const (
+1 -1
View File
@@ -3,7 +3,7 @@ package auth
import (
"context"
"shared-album/internal/models"
"galo/internal/models"
)
// Repository is the persistence contract for the auth domain.
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"strings"
"time"
"shared-album/internal/httpx"
"shared-album/internal/models"
"galo/internal/httpx"
"galo/internal/models"
)
type TokenPair struct {
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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")
+1 -1
View File
@@ -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{
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"path/filepath"
"testing"
assets "shared-album"
assets "galo"
)
func TestMigrateSQLite(t *testing.T) {
+9 -9
View File
@@ -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 {
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -3,7 +3,7 @@ package members
import (
"context"
"shared-album/internal/models"
"galo/internal/models"
)
// Repository is the persistence contract for the members domain.
+5 -5
View File
@@ -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 {
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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")
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -3,7 +3,7 @@ package notifications
import (
"context"
"shared-album/internal/models"
"galo/internal/models"
)
// Repository is the persistence contract for the notifications domain.
+4 -4
View File
@@ -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 {
@@ -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.
+1 -1
View File
@@ -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")
+2 -2
View File
@@ -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
+6 -6
View File
@@ -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 {
+1 -1
View File
@@ -8,7 +8,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"shared-album/internal/auth"
"galo/internal/auth"
)
func TestObjectStateTransitions(t *testing.T) {
+1 -1
View File
@@ -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
+6 -6
View File
@@ -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 {
+1 -1
View File
@@ -3,7 +3,7 @@ package photos
import (
"time"
"shared-album/internal/sqliteutil"
"galo/internal/sqliteutil"
)
func nullIfEmpty(s string) any {
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"errors"
"time"
"shared-album/internal/sqliteutil"
"galo/internal/sqliteutil"
)
// CreateObject inserts a new object row in the pending state.
+3 -3
View File
@@ -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.
+2 -2
View File
@@ -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")
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"log/slog"
"time"
"shared-album/internal/auth"
"galo/internal/auth"
)
const maxVariantAttempts = 5
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"github.com/jackc/pgx/v5/pgxpool"
"shared-album/internal/storage"
"galo/internal/storage"
)
func TestWorkerGeneratesVariantsAndCollects(t *testing.T) {
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -5,7 +5,7 @@ import (
"testing"
"time"
"shared-album/internal/storage"
"galo/internal/storage"
)
func TestClassify(t *testing.T) {
+9 -9
View File
@@ -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
+10 -10
View File
@@ -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
+10 -10
View File
@@ -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) {
+6 -6
View File
@@ -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 {
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"fmt"
"time"
"shared-album/internal/sqliteutil"
"galo/internal/sqliteutil"
)
// SQLiteStore is the SQLite implementation of Repository.
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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.
+4 -4
View File
@@ -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 {
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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")
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -3,7 +3,7 @@ package social
import (
"context"
"shared-album/internal/models"
"galo/internal/models"
)
// Repository is the persistence contract for the social domain.
+5 -5
View File
@@ -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 {
+2 -2
View File
@@ -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.
+1 -1
View File
@@ -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")
+1 -1
View File
@@ -13,7 +13,7 @@ import (
"testing"
"time"
"shared-album/internal/config"
"galo/internal/config"
)
func newTestS3(t *testing.T) (*S3, *Signer) {
+1 -1
View File
@@ -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,
+8 -8
View File
@@ -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.
+2 -2
View File
@@ -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) {