docker setup
This commit is contained in:
@@ -14,6 +14,18 @@ import { FeatureAvailabilityGuard } from './domain/policy/FeatureAvailabilityGua
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule, process.env.GENERATE_OPENAPI ? { logger: false } : undefined);
|
||||
|
||||
// Website runs on a different origin in dev/docker (e.g. http://localhost:3000 -> http://localhost:3001),
|
||||
// and our website HTTP client uses `credentials: 'include'`, so we must support CORS with credentials.
|
||||
app.enableCors({
|
||||
credentials: true,
|
||||
origin: (origin, callback) => {
|
||||
if (!origin) {
|
||||
return callback(null, false);
|
||||
}
|
||||
return callback(null, origin);
|
||||
},
|
||||
});
|
||||
|
||||
app.useGlobalPipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
|
||||
@@ -378,13 +378,10 @@ export default function LeaguesPage() {
|
||||
const [activeCategory, setActiveCategory] = useState<CategoryId>('all');
|
||||
const [showFilters, setShowFilters] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
void loadLeagues();
|
||||
}, []);
|
||||
const { leagueService } = useServices();
|
||||
|
||||
const loadLeagues = async () => {
|
||||
const loadLeagues = useCallback(async () => {
|
||||
try {
|
||||
const { leagueService } = useServices();
|
||||
const leagues = await leagueService.getAllLeagues();
|
||||
setRealLeagues(leagues);
|
||||
} catch (error) {
|
||||
@@ -392,7 +389,11 @@ export default function LeaguesPage() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
}, [leagueService]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadLeagues();
|
||||
}, [loadLeagues]);
|
||||
|
||||
const leagues = realLeagues;
|
||||
|
||||
|
||||
@@ -14,13 +14,11 @@ import SimPlatformMockup from '@/components/mockups/SimPlatformMockup';
|
||||
import MockupStack from '@/components/ui/MockupStack';
|
||||
import Card from '@/components/ui/Card';
|
||||
import Button from '@/components/ui/Button';
|
||||
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
||||
import { ServiceFactory } from '@/lib/services/ServiceFactory';
|
||||
|
||||
export default async function HomePage() {
|
||||
const baseUrl =
|
||||
process.env.API_BASE_URL ??
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ??
|
||||
'http://api:3000';
|
||||
const baseUrl = getWebsiteApiBaseUrl();
|
||||
const serviceFactory = new ServiceFactory(baseUrl);
|
||||
const sessionService = serviceFactory.createSessionService();
|
||||
const landingService = serviceFactory.createLandingService();
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ApiClient } from './api/index';
|
||||
import { getWebsiteApiBaseUrl } from './config/apiBaseUrl';
|
||||
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001';
|
||||
|
||||
export const apiClient = new ApiClient(API_BASE_URL);
|
||||
export const apiClient = new ApiClient(getWebsiteApiBaseUrl());
|
||||
36
apps/website/lib/config/apiBaseUrl.ts
Normal file
36
apps/website/lib/config/apiBaseUrl.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
function normalizeBaseUrl(raw: string): string {
|
||||
const trimmed = raw.trim();
|
||||
return trimmed.endsWith('/') ? trimmed.slice(0, -1) : trimmed;
|
||||
}
|
||||
|
||||
export function getWebsiteApiBaseUrl(): string {
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
const configured = isBrowser
|
||||
? process.env.NEXT_PUBLIC_API_BASE_URL
|
||||
: process.env.API_BASE_URL ?? process.env.NEXT_PUBLIC_API_BASE_URL;
|
||||
|
||||
if (configured && configured.trim()) {
|
||||
return normalizeBaseUrl(configured);
|
||||
}
|
||||
|
||||
const isTestLike =
|
||||
process.env.NODE_ENV === 'test' ||
|
||||
process.env.CI === 'true' ||
|
||||
process.env.DOCKER === 'true';
|
||||
|
||||
if (isTestLike) {
|
||||
throw new Error(
|
||||
isBrowser
|
||||
? 'Missing NEXT_PUBLIC_API_BASE_URL. In Docker/CI/test we do not allow falling back to localhost.'
|
||||
: 'Missing API_BASE_URL. In Docker/CI/test we do not allow falling back to localhost.',
|
||||
);
|
||||
}
|
||||
|
||||
const fallback =
|
||||
process.env.NODE_ENV === 'development'
|
||||
? 'http://localhost:3001'
|
||||
: 'http://api:3000';
|
||||
|
||||
return normalizeBaseUrl(fallback);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { DashboardApiClient } from '../api/dashboard/DashboardApiClient';
|
||||
import { PolicyApiClient } from '../api/policy/PolicyApiClient';
|
||||
import { ProtestsApiClient } from '../api/protests/ProtestsApiClient';
|
||||
import { PenaltiesApiClient } from '../api/penalties/PenaltiesApiClient';
|
||||
import { getWebsiteApiBaseUrl } from '../config/apiBaseUrl';
|
||||
import { PenaltyService } from './penalties/PenaltyService';
|
||||
import { ConsoleErrorReporter } from '../infrastructure/logging/ConsoleErrorReporter';
|
||||
import { ConsoleLogger } from '../infrastructure/logging/ConsoleLogger';
|
||||
@@ -102,7 +103,7 @@ export class ServiceFactory {
|
||||
|
||||
private static getDefaultInstance(): ServiceFactory {
|
||||
if (!this.defaultInstance) {
|
||||
this.defaultInstance = new ServiceFactory(process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001');
|
||||
this.defaultInstance = new ServiceFactory(getWebsiteApiBaseUrl());
|
||||
}
|
||||
return this.defaultInstance;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { createContext, ReactNode, useContext, useMemo } from 'react';
|
||||
import { getWebsiteApiBaseUrl } from '../config/apiBaseUrl';
|
||||
import { ServiceFactory } from './ServiceFactory';
|
||||
|
||||
// Import all service types
|
||||
@@ -82,7 +83,7 @@ interface ServiceProviderProps {
|
||||
|
||||
export function ServiceProvider({ children }: ServiceProviderProps) {
|
||||
const services = useMemo(() => {
|
||||
const serviceFactory = new ServiceFactory(process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3001');
|
||||
const serviceFactory = new ServiceFactory(getWebsiteApiBaseUrl());
|
||||
|
||||
return {
|
||||
raceService: serviceFactory.createRaceService(),
|
||||
|
||||
Reference in New Issue
Block a user