Merge remote-tracking branch 'origin/main'
Some checks failed
Workflow / ⚫️ Test (push) Has been cancelled
Workflow / ʦ TypeScript (push) Has been cancelled

# Conflicts:
#	docker-compose.yml
This commit is contained in:
T. Zehetbauer
2026-04-01 13:30:00 +02:00
5 changed files with 77 additions and 86 deletions

View File

@@ -5,7 +5,7 @@ WORKDIR /app
# --- Install + Build in one stage ---
FROM base AS builder
# CACHE_BUST: change this value to force a full rebuild (busts Docker layer cache)
ARG CACHE_BUST=11
ARG CACHE_BUST=12
RUN echo "Cache bust: ${CACHE_BUST}"
COPY . .
RUN pnpm install --no-frozen-lockfile
@@ -17,10 +17,16 @@ ARG NEXT_PUBLIC_SITE_URL=https://myeasycms.de
ARG NEXT_PUBLIC_SUPABASE_URL=http://localhost:8000
ARG NEXT_PUBLIC_SUPABASE_PUBLIC_KEY
ARG NEXT_PUBLIC_DEFAULT_LOCALE=de
ARG NEXT_PUBLIC_ENABLE_FISCHEREI=true
ARG NEXT_PUBLIC_ENABLE_MEETING_PROTOCOLS=true
ARG NEXT_PUBLIC_ENABLE_VERBANDSVERWALTUNG=true
ENV NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL}
ENV NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
ENV NEXT_PUBLIC_SUPABASE_PUBLIC_KEY=${NEXT_PUBLIC_SUPABASE_PUBLIC_KEY}
ENV NEXT_PUBLIC_DEFAULT_LOCALE=${NEXT_PUBLIC_DEFAULT_LOCALE}
ENV NEXT_PUBLIC_ENABLE_FISCHEREI=${NEXT_PUBLIC_ENABLE_FISCHEREI}
ENV NEXT_PUBLIC_ENABLE_MEETING_PROTOCOLS=${NEXT_PUBLIC_ENABLE_MEETING_PROTOCOLS}
ENV NEXT_PUBLIC_ENABLE_VERBANDSVERWALTUNG=${NEXT_PUBLIC_ENABLE_VERBANDSVERWALTUNG}
RUN pnpm --filter web build
# --- Run ---

View File

@@ -28,7 +28,7 @@ services:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: postgres
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres -d postgres']
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 10s
timeout: 5s
retries: 10
@@ -49,7 +49,7 @@ services:
environment:
PGPASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
entrypoint: ['/bin/sh', '-c']
entrypoint: ["/bin/sh", "-c"]
command:
- |
echo "🔑 Ensuring role passwords are set (idempotent)..."
@@ -63,7 +63,7 @@ services:
echo "✅ App migrations complete."
echo ""
sh /app-seed/dev-bootstrap.sh
restart: 'no'
restart: "no"
# =====================================================
# Supabase Auth (GoTrue)
@@ -102,15 +102,7 @@ services:
GOTRUE_MAILER_URLPATHS_RECOVERY: /auth/v1/verify
GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: /auth/v1/verify
healthcheck:
test:
[
'CMD',
'wget',
'--no-verbose',
'--tries=1',
'--spider',
'http://localhost:9999/health',
]
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9999/health"]
interval: 10s
timeout: 5s
retries: 5
@@ -131,9 +123,9 @@ services:
PGRST_DB_SCHEMAS: public,storage,graphql_public
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
PGRST_DB_USE_LEGACY_GUCS: 'false'
PGRST_DB_USE_LEGACY_GUCS: "false"
healthcheck:
test: ['CMD-SHELL', 'head -c0 </dev/tcp/localhost/3000 || exit 1']
test: ["CMD-SHELL", "head -c0 </dev/tcp/localhost/3000 || exit 1"]
interval: 10s
timeout: 5s
retries: 5
@@ -157,20 +149,20 @@ services:
DB_USER: supabase_admin
DB_PASSWORD: ${POSTGRES_PASSWORD}
DB_NAME: postgres
DB_AFTER_CONNECT_QUERY: 'SET search_path TO _realtime'
DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
DB_ENC_KEY: supabaserealtime
API_JWT_SECRET: ${JWT_SECRET}
SECRET_KEY_BASE: ${SECRET_KEY_BASE:-UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq}
ERL_AFLAGS: '-proto_dist inet_tcp'
ERL_AFLAGS: "-proto_dist inet_tcp"
DNS_NODES: "''"
RLIMIT_NOFILE: '10000'
RLIMIT_NOFILE: "10000"
APP_NAME: realtime
SEED_SELF_HOST: 'true'
SEED_SELF_HOST: "true"
REPLICATION_MODE: RLS
REPLICATION_POLL_INTERVAL: 100
SECURE_CHANNELS: 'true'
SECURE_CHANNELS: "true"
SLOT_NAME: supabase_realtime_rls
TEMPORARY_SLOT: 'true'
TEMPORARY_SLOT: "true"
MAX_RECORD_BYTES: 1048576
# =====================================================
@@ -204,11 +196,7 @@ services:
GLOBAL_S3_BUCKET: stub
IMGPROXY_URL: http://supabase-imgproxy:8080
healthcheck:
test:
[
'CMD-SHELL',
'wget --no-verbose --tries=1 --spider http://localhost:5000/status || exit 1',
]
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5000/status || exit 1"]
interval: 10s
timeout: 5s
retries: 5
@@ -221,10 +209,10 @@ services:
image: darthsim/imgproxy:v3.8.0
restart: unless-stopped
environment:
IMGPROXY_BIND: ':8080'
IMGPROXY_BIND: ":8080"
IMGPROXY_LOCAL_FILESYSTEM_ROOT: /
IMGPROXY_USE_ETAG: 'true'
IMGPROXY_ENABLE_WEBP_DETECTION: 'true'
IMGPROXY_USE_ETAG: "true"
IMGPROXY_ENABLE_WEBP_DETECTION: "true"
# =====================================================
# Supabase pg_meta (DB introspection for Studio)
@@ -264,16 +252,10 @@ services:
SUPABASE_ANON_KEY: ${SUPABASE_ANON_KEY}
SUPABASE_SERVICE_KEY: ${SUPABASE_SERVICE_ROLE_KEY}
AUTH_JWT_SECRET: ${JWT_SECRET}
NEXT_PUBLIC_ENABLE_LOGS: 'true'
NEXT_PUBLIC_ENABLE_LOGS: "true"
NEXT_ANALYTICS_BACKEND_PROVIDER: postgres
healthcheck:
test:
[
'CMD',
'node',
'-e',
"require('http').get('http://localhost:3000/api/profile', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))",
]
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/profile', (r) => r.statusCode === 200 ? process.exit(0) : process.exit(1))"]
interval: 10s
timeout: 5s
retries: 5
@@ -302,7 +284,7 @@ services:
entrypoint: >
sh -c "sed 's|\$${SUPABASE_ANON_KEY}|'\"$$SUPABASE_ANON_KEY\"'|g; s|\$${SUPABASE_SERVICE_KEY}|'\"$$SUPABASE_SERVICE_KEY\"'|g' /var/lib/kong/kong.yml.tpl > /tmp/kong.yml && KONG_DECLARATIVE_CONFIG=/tmp/kong.yml /docker-entrypoint.sh kong docker-start"
environment:
KONG_DATABASE: 'off'
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /var/lib/kong/kong.yml
KONG_DNS_ORDER: LAST,A,CNAME
KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
@@ -313,7 +295,7 @@ services:
volumes:
- ./docker/kong.yml:/var/lib/kong/kong.yml.tpl:ro
healthcheck:
test: ['CMD', 'kong', 'health']
test: ["CMD", "kong", "health"]
interval: 10s
timeout: 5s
retries: 5
@@ -347,12 +329,15 @@ services:
SUPABASE_DB_WEBHOOK_SECRET: ${DB_WEBHOOK_SECRET:-webhooksecret}
EMAIL_SENDER: ${EMAIL_SENDER:-noreply@myeasycms.de}
NEXT_PUBLIC_PRODUCT_NAME: MyEasyCMS
NEXT_PUBLIC_ENABLE_THEME_TOGGLE: 'true'
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS: 'true'
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATION: 'true'
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING: 'false'
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING: 'false'
NEXT_PUBLIC_ENABLE_NOTIFICATIONS: 'true'
NEXT_PUBLIC_ENABLE_THEME_TOGGLE: "true"
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS: "true"
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATION: "true"
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING: "false"
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING: "false"
NEXT_PUBLIC_ENABLE_NOTIFICATIONS: "true"
NEXT_PUBLIC_ENABLE_FISCHEREI: "true"
NEXT_PUBLIC_ENABLE_MEETING_PROTOCOLS: "true"
NEXT_PUBLIC_ENABLE_VERBANDSVERWALTUNG: "true"
volumes:
supabase-db-data:

View File

@@ -98,18 +98,18 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
short_name: input.shortName,
short_name: input.shortName || null,
water_type: input.waterType,
description: input.description,
description: input.description || null,
surface_area_ha: input.surfaceAreaHa,
length_m: input.lengthM,
width_m: input.widthM,
avg_depth_m: input.avgDepthM,
max_depth_m: input.maxDepthM,
outflow: input.outflow,
location: input.location,
outflow: input.outflow || null,
location: input.location || null,
classification_order: input.classificationOrder,
county: input.county,
county: input.county || null,
geo_lat: input.geoLat,
geo_lng: input.geoLng,
lfv_number: input.lfvNumber,
@@ -298,17 +298,17 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
name_latin: input.nameLatin,
name_local: input.nameLocal,
name_latin: input.nameLatin || null,
name_local: input.nameLocal || null,
is_active: input.isActive,
max_age_years: input.maxAgeYears,
max_weight_kg: input.maxWeightKg,
max_length_cm: input.maxLengthCm,
protected_min_size_cm: input.protectedMinSizeCm,
protection_period_start: input.protectionPeriodStart,
protection_period_end: input.protectionPeriodEnd,
spawning_season_start: input.spawningSeasonStart,
spawning_season_end: input.spawningSeasonEnd,
protection_period_start: input.protectionPeriodStart || null,
protection_period_end: input.protectionPeriodEnd || null,
spawning_season_start: input.spawningSeasonStart || null,
spawning_season_end: input.spawningSeasonEnd || null,
has_special_spawning_season: input.hasSpecialSpawningSeason,
k_factor_avg: input.kFactorAvg,
k_factor_min: input.kFactorMin,
@@ -408,8 +408,8 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
water_id: input.waterId,
species_id: input.speciesId,
min_size_cm: input.minSizeCm,
protection_period_start: input.protectionPeriodStart,
protection_period_end: input.protectionPeriodEnd,
protection_period_start: input.protectionPeriodStart || null,
protection_period_end: input.protectionPeriodEnd || null,
max_catch_per_day: input.maxCatchPerDay,
max_catch_per_year: input.maxCatchPerYear,
},
@@ -480,13 +480,13 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
account_id: input.accountId,
water_id: input.waterId,
species_id: input.speciesId,
stocking_date: input.stockingDate,
stocking_date: input.stockingDate || null,
quantity: input.quantity,
weight_kg: input.weightKg,
age_class: input.ageClass,
cost_euros: input.costEuros,
supplier_id: input.supplierId,
remarks: input.remarks,
remarks: input.remarks || null,
created_by: userId,
updated_by: userId,
})
@@ -589,11 +589,11 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
account_id: input.accountId,
water_id: input.waterId,
lessor_name: input.lessorName,
lessor_address: input.lessorAddress,
lessor_phone: input.lessorPhone,
lessor_email: input.lessorEmail,
start_date: input.startDate,
end_date: input.endDate,
lessor_address: input.lessorAddress || null,
lessor_phone: input.lessorPhone || null,
lessor_email: input.lessorEmail || null,
start_date: input.startDate || null,
end_date: input.endDate || null,
duration_years: input.durationYears,
initial_amount: input.initialAmount,
fixed_annual_increase: input.fixedAnnualIncrease,
@@ -728,14 +728,14 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
member_id: input.memberId,
year: input.year,
member_name: input.memberName,
member_birth_date: input.memberBirthDate,
member_birth_date: input.memberBirthDate || null,
fishing_days_count: input.fishingDaysCount,
card_numbers: input.cardNumbers,
is_fly_fisher: input.isFlyFisher,
is_hejfish: input.isHejfish,
is_empty: input.isEmpty,
not_fished: input.notFished,
remarks: input.remarks,
remarks: input.remarks || null,
created_by: userId,
updated_by: userId,
})
@@ -859,7 +859,7 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
species_id: input.speciesId,
water_id: input.waterId,
member_id: input.memberId,
catch_date: input.catchDate,
catch_date: input.catchDate || null,
quantity: input.quantity,
length_cm: input.lengthCm,
weight_g: input.weightG,
@@ -871,7 +871,7 @@ export function createFischereiApi(client: SupabaseClient<Database>) {
competition_id: input.competitionId,
competition_participant_id: input.competitionParticipantId,
permit_id: input.permitId,
remarks: input.remarks,
remarks: input.remarks || null,
})
.select()
.single();

View File

@@ -80,9 +80,9 @@ export function createMeetingsApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
title: input.title,
meeting_date: input.meetingDate,
meeting_date: input.meetingDate || null,
meeting_type: input.meetingType,
location: input.location,
location: input.location || null,
attendees: input.attendees,
remarks: input.remarks,
is_published: input.isPublished,

View File

@@ -102,19 +102,19 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
short_name: input.shortName,
short_name: input.shortName || null,
association_type_id: input.associationTypeId,
member_count: input.memberCount,
founded_year: input.foundedYear,
street: input.street,
zip: input.zip,
city: input.city,
phone: input.phone,
email: input.email,
website: input.website,
iban: input.iban,
bic: input.bic,
account_holder: input.accountHolder,
phone: input.phone || null,
email: input.email || null,
website: input.website || null,
iban: input.iban || null,
bic: input.bic || null,
account_holder: input.accountHolder || null,
is_archived: input.isArchived,
created_by: userId,
updated_by: userId,
@@ -248,8 +248,8 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
first_name: input.firstName,
last_name: input.lastName,
role: input.role,
phone: input.phone,
email: input.email,
phone: input.phone || null,
email: input.email || null,
is_primary: input.isPrimary,
})
.select()
@@ -309,7 +309,7 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
description: input.description,
description: input.description || null,
sort_order: input.sortOrder,
})
.select()
@@ -368,7 +368,7 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
description: input.description,
description: input.description || null,
sort_order: input.sortOrder,
})
.select()
@@ -427,7 +427,7 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
.insert({
account_id: input.accountId,
name: input.name,
description: input.description,
description: input.description || null,
default_amount: input.defaultAmount,
is_active: input.isActive,
})
@@ -532,8 +532,8 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
fee_type_id: input.feeTypeId,
year: input.year,
amount: input.amount,
due_date: input.dueDate,
paid_date: input.paidDate,
due_date: input.dueDate || null,
paid_date: input.paidDate || null,
payment_method: input.paymentMethod,
status: input.status,
notes: input.notes,
@@ -605,7 +605,7 @@ export function createVerbandApi(client: SupabaseClient<Database>) {
title: input.title,
content: input.content,
note_type: input.noteType,
due_date: input.dueDate,
due_date: input.dueDate || null,
is_completed: input.isCompleted,
})
.select()