Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c3a5f97cc | ||
|
|
2ccfb9ccd6 |
@@ -67,6 +67,15 @@ RUN echo 'server { \
|
|||||||
proxy_set_header X-Real-IP $remote_addr; \
|
proxy_set_header X-Real-IP $remote_addr; \
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
||||||
} \
|
} \
|
||||||
|
location /__supabase/ { \
|
||||||
|
proxy_pass http://192.168.0.94:8000/; \
|
||||||
|
proxy_set_header Host $host; \
|
||||||
|
proxy_set_header X-Real-IP $remote_addr; \
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \
|
||||||
|
proxy_set_header Upgrade $http_upgrade; \
|
||||||
|
proxy_set_header Connection "upgrade"; \
|
||||||
|
proxy_http_version 1.1; \
|
||||||
|
} \
|
||||||
location /api/ { \
|
location /api/ { \
|
||||||
proxy_pass http://192.168.0.64:18000/api/; \
|
proxy_pass http://192.168.0.64:18000/api/; \
|
||||||
proxy_set_header Host $host; \
|
proxy_set_header Host $host; \
|
||||||
|
|||||||
@@ -20,16 +20,21 @@ services:
|
|||||||
# same-origin and pass through Dockerfile's /__ccapi proxy. The proxy
|
# same-origin and pass through Dockerfile's /__ccapi proxy. The proxy
|
||||||
# strips that prefix before forwarding, preserving mixed backend routes
|
# strips that prefix before forwarding, preserving mixed backend routes
|
||||||
# such as /api/exam, /me/bootstrap, and /database/timetable.
|
# such as /api/exam, /me/bootstrap, and /database/timetable.
|
||||||
# .env.dev still points at the LAN API for local Vite/dev tooling.
|
# Supabase is likewise routed same-origin via Dockerfile's /__supabase
|
||||||
|
# proxy -> dev Supabase .94 (no CORS, browser-network-agnostic). The
|
||||||
|
# leading-slash URL is resolved against window.location.origin in
|
||||||
|
# supabaseClient.ts. Provide the matching .94 anon key as a build arg
|
||||||
|
# (VITE_SUPABASE_ANON_KEY) so it pairs with the .94 backend.
|
||||||
|
# .env.dev still points at the LAN API/Supabase for local Vite/dev tooling.
|
||||||
VITE_API_BASE: /__ccapi
|
VITE_API_BASE: /__ccapi
|
||||||
VITE_API_URL: /__ccapi
|
VITE_API_URL: /__ccapi
|
||||||
|
VITE_SUPABASE_URL: /__supabase
|
||||||
VITE_APP_NAME: ${VITE_APP_NAME:-Classroom Copilot}
|
VITE_APP_NAME: ${VITE_APP_NAME:-Classroom Copilot}
|
||||||
VITE_APP_HMR_URL: ${VITE_APP_HMR_URL:-}
|
VITE_APP_HMR_URL: ${VITE_APP_HMR_URL:-}
|
||||||
VITE_DEV: ${VITE_DEV:-false}
|
VITE_DEV: ${VITE_DEV:-false}
|
||||||
VITE_FRONTEND_SITE_URL: ${VITE_FRONTEND_SITE_URL:-}
|
VITE_FRONTEND_SITE_URL: ${VITE_FRONTEND_SITE_URL:-}
|
||||||
VITE_SEARCH_URL: ${VITE_SEARCH_URL:-}
|
VITE_SEARCH_URL: ${VITE_SEARCH_URL:-}
|
||||||
VITE_SUPABASE_ANON_KEY: ${VITE_SUPABASE_ANON_KEY:-}
|
VITE_SUPABASE_ANON_KEY: ${VITE_SUPABASE_ANON_KEY:-}
|
||||||
VITE_SUPABASE_URL: ${VITE_SUPABASE_URL:-}
|
|
||||||
VITE_SUPER_ADMIN_EMAIL: ${VITE_SUPER_ADMIN_EMAIL:-}
|
VITE_SUPER_ADMIN_EMAIL: ${VITE_SUPER_ADMIN_EMAIL:-}
|
||||||
VITE_TLSYNC_URL: ${VITE_TLSYNC_URL:-}
|
VITE_TLSYNC_URL: ${VITE_TLSYNC_URL:-}
|
||||||
VITE_WHISPERLIVE_URL: ${VITE_WHISPERLIVE_URL:-}
|
VITE_WHISPERLIVE_URL: ${VITE_WHISPERLIVE_URL:-}
|
||||||
|
|||||||
@@ -102,6 +102,17 @@ const PlatformAdminPage: React.FC = () => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<Alert severity="warning" sx={{ mb: 3 }}>
|
||||||
|
<Typography variant="subtitle2" sx={{ fontWeight: 700 }}>Destructive reset scope: exam-corpus</Typography>
|
||||||
|
<Typography variant="body2">
|
||||||
|
The <strong>exam-corpus</strong> reset is not limited to public papers. It wipes the entire
|
||||||
|
exam-marker subsystem: public corpus/eb_* data, cc.examboards storage, templates, template
|
||||||
|
layouts, questions, boundaries, response areas, marking batches, student submissions, and
|
||||||
|
mark entries. Use it only when you intend to rebuild all exam-marker data; it does not reset
|
||||||
|
schools, users, or timetable data.
|
||||||
|
</Typography>
|
||||||
|
</Alert>
|
||||||
|
|
||||||
<Typography variant="subtitle2" sx={{ mb: 1 }}>Schools ({loading ? '…' : schools.length})</Typography>
|
<Typography variant="subtitle2" sx={{ mb: 1 }}>Schools ({loading ? '…' : schools.length})</Typography>
|
||||||
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import { createClient, SupabaseClient } from '@supabase/supabase-js';
|
import { createClient, SupabaseClient } from '@supabase/supabase-js';
|
||||||
import { logger } from './debugConfig';
|
import { logger } from './debugConfig';
|
||||||
|
|
||||||
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
const rawSupabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
||||||
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
|
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
|
||||||
|
|
||||||
|
// Same-origin proxy support: a leading-slash value (e.g. "/__supabase") is
|
||||||
|
// resolved against the current browser origin so supabase-js receives an
|
||||||
|
// absolute URL while every request stays same-origin (no CORS) and routes
|
||||||
|
// through the app host's /__supabase nginx proxy to the backend Supabase.
|
||||||
|
const supabaseUrl = rawSupabaseUrl?.startsWith('/')
|
||||||
|
? `${window.location.origin}${rawSupabaseUrl}`
|
||||||
|
: rawSupabaseUrl;
|
||||||
|
|
||||||
if (!supabaseUrl || !supabaseAnonKey) {
|
if (!supabaseUrl || !supabaseAnonKey) {
|
||||||
throw new Error('Missing Supabase configuration');
|
throw new Error('Missing Supabase configuration');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user