iclubmedasu/members-portal
iClub Members Portal
Next.js frontend for the iClub members portal. Deployed as a Docker Space on Hugging Face.
Environment Variables
Set these in Space Settings → Variables (not Secrets). Runtime vars apply without rebuild; NEXT_PUBLIC_* are inlined at Docker build time.
TEMPORARY — HF direct API
Default = direct browser → backend. Portal UI still serves from this Space; API traffic does not hop Space→Space via /backend-api (avoids HF 502/429 on the BFF). Auth uses Authorization: Bearer + localStorage (temporary tradeoff; XSS can read the token). Cross-origin fetches use credentials: "omit".
This does not wake a sleeping portal Space — keep /api/health keep-alive for that.
Reversal (restore BFF)
- Set Space Variable
NEXT_PUBLIC_PORTAL_USE_BFF=true. - Confirm
NEXT_PUBLIC_API_URL=https://iclubmedasu-backend.hf.space/api(or/backend-api). - Confirm runtime
BACKEND_API_URLand matchingBFF_PROXY_SECRETon portal + backend. - Rebuild the portal Space (build-time vars are baked into the Next bundle).
BFF route + bffProxy code remain in the repo; unused while the flag is off.
Why /backend-api exists (when BFF is on)
Hugging Face Spaces edge often answers CORS preflight without Access-Control-Allow-Credentials: true. Credentialed fetch from members-portal.hf.space → backend.hf.space then fails. The portal proxies /backend-api/* server-side to {BACKEND_API_URL}/api/* so the browser stays same-origin. The BFF also forwards the browser IP (with BFF_PROXY_SECRET) and retries once on HF HTML/502/503 blips without retrying Express JSON 429.
