Skip to content

Infrastruktura i Deployment

Projekt Lumos Islands składa się z trzech komponentów:

  • Flutter App (iOS + Android) — budowane lokalnie na macOS
  • Manager-Content (Go server) — deployment w Docker
  • IDEA (VitePress docs) — statyczna strona

Supabase (BaaS)

Supabase jako backend-as-a-service:

Baza danych — PostgreSQL (hosted by Supabase)

  • Migracje: supabase migration CLI
  • Row Level Security (RLS) na tabelach
  • Supabase client w Go (supabase-go lub bezpośrednio pgx/sqlx do PostgreSQL URL)

Storage — Supabase Storage (S3-compatible)

  • Buckety: avatars, media (video, audio, images), creative-submissions
  • Public bucket dla preset avatarów i media content
  • Private bucket dla creative submissions
  • CDN: Supabase CDN (automatyczny)
  • Upload przez Go server (nie bezpośrednio z Flutter)
  • Limity: avatar 2MB, media 100MB, creative 10MB

Auth — Supabase Auth (uzupełniające)

  • Supabase Auth używany do emaili (wysyłanie kodów weryfikacyjnych)
  • Własna warstwa JWT w Go server (nie Supabase Auth bezpośrednio dla app auth)
  • Email templates konfigurowane w Supabase Dashboard

Realtime — Supabase Realtime (opcjonalnie w przyszłości)

  • Broadcast do push notifications
  • Na start: polling, później migration do realtime

JWT Specyfikacja

  • Algorytm: HS256
  • Secret: env var JWT_SECRET (min 32 znaki)
  • Expiry: 30 dni (child), 7 dni (parent)
  • Claims: { "sub": "user_id", "role": "child|parent|school", "iat": ..., "exp": ... }
  • Refresh: brak refresh tokena w v1 — po wygaśnięciu ponowne logowanie (PIN jest szybki)
  • Logout: usunięcie tokena z Flutter Secure Storage (stateless JWT, brak server-side revocation w v1)

Docker Deployment (Manager-Content)

dockerfile
# Multi-stage build
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server ./cmd/server

FROM alpine:3.19
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /server
COPY --from=builder /app/web /web
EXPOSE 8080
CMD ["/server"]

Docker Compose (dev):

yaml
services:
  manager:
    build: ./manager-content
    ports: ["8080:8080"]
    env_file: .env
    volumes:
      - ./manager-content:/app  # hot reload z air

Environment variables:

ZmiennaOpisPrzykład
DATABASE_URLSupabase PostgreSQL connection stringpostgresql://...
SUPABASE_URLSupabase project URLhttps://xxx.supabase.co
SUPABASE_SERVICE_KEYSupabase service role keyeyJ...
JWT_SECRETSecret do podpisywania JWTsuper-secret-key-32-chars-min
PORTPort serwera8080
ENVŚrodowiskodevelopment / production

GitHub Actions CI/CD

Plik: .github/workflows/deploy.yml

Trigger: push na main

Steps:

  1. Checkout
  2. Go tests (go test ./...)
  3. Build Docker image
  4. Push do GitHub Container Registry (ghcr.io)
  5. Deploy (SSH do serwera, docker pull + restart)
yaml
name: Deploy Manager-Content
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
      - run: go test ./...

  build-push:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          context: ./manager-content
          push: true
          tags: ghcr.io/${{ github.repository }}/manager:latest

Flutter App Build (macOS)

Budowane lokalnie na macOS. Makefile w katalogu app/:

makefile
.PHONY: build run test

# Zbuduj i wyślij do App Store (iOS)
build-ios:
	flutter build ipa --release
	xcrun altool --upload-app \
		--type ios \
		--file build/ios/ipa/*.ipa \
		--apiKey $(APP_STORE_API_KEY) \
		--apiIssuer $(APP_STORE_ISSUER)

# Zbuduj APK (Android)
build-android:
	flutter build appbundle --release

# Zbuduj obie platformy
build: build-ios build-android

# Uruchom lokalne
run:
	flutter run

# Testy
test:
	flutter test

Wymagane:

  • macOS z Xcode 15+
  • Flutter SDK 3.x
  • Apple Developer Account + API Key
  • APP_STORE_API_KEY i APP_STORE_ISSUER w .env lub export

Monitoring i Logi

  • Go server: structured logging (slog) w JSON
  • Docker logs -> stdout/stderr
  • Health check: GET /health -> 200 OK
  • Supabase Dashboard: monitoring bazy danych
  • Sentry (opcjonalnie): error tracking w Go + Flutter

CORS

go
cors := cors.New(cors.Options{
    AllowedOrigins:   []string{"https://manager.lumosislands.com"},
    AllowedMethods:   []string{"GET", "POST", "PATCH", "DELETE"},
    AllowedHeaders:   []string{"Authorization", "Content-Type", "Device-Id"},
    AllowCredentials: true,
})

Flutter app (/app/*): brak CORS (natywna apka, nie przeglądarka)

Rate Limiting

EndpointLimitWindow
POST /app/auth/*10 req1 min
POST /api/auth/*10 req1 min
GET /app/*100 req1 min
POST /app/*30 req1 min
Uploady (multipart)5 req1 min

Implementacja: middleware w chi (in-memory, per IP)

Lumos Islands v2 - Dokumentacja Projektowa