@@ -280,6 +280,12 @@ Flow:
280280#### llm-proxy
281281Gestisce la crittografia e il proxy delle API keys verso OpenAI/Anthropic.
282282
283+ ** Autenticazione:**
284+ - JWT verification disabilitata a livello gateway (` verify_jwt = false ` )
285+ - Autenticazione gestita internamente dalla funzione per ogni azione
286+ - ` test_key ` : non richiede autenticazione (solo validazione chiave esterna)
287+ - Tutte le altre azioni: richiedono JWT valido via ` getUserId() `
288+
283289** Azioni disponibili:**
284290
285291| Action | Descrizione |
@@ -399,6 +405,37 @@ export const signInWithGoogle = async () => {
399405};
400406```
401407
408+ ### 5.2 Session Token Management
409+
410+ Per evitare rate limiting, il refresh del token viene eseguito solo quando necessario:
411+
412+ ``` typescript
413+ // packages/core/src/supabase/auth.ts
414+ export async function getAccessToken(): Promise <string | null > {
415+ const { data : { session } } = await supabase .auth .getSession ();
416+
417+ if (! session ) return null ;
418+
419+ // Refresh solo se il token scade entro 60 secondi
420+ const expiresAt = session .expires_at ;
421+ const now = Math .floor (Date .now () / 1000 );
422+ const needsRefresh = expiresAt && (expiresAt - now ) < 60 ;
423+
424+ if (needsRefresh ) {
425+ const { data, error } = await supabase .auth .refreshSession ();
426+ if (error ) {
427+ console .error (' Failed to refresh session:' , error );
428+ return session .access_token ; // Fallback al token corrente
429+ }
430+ return data .session ?.access_token || null ;
431+ }
432+
433+ return session .access_token ;
434+ }
435+ ```
436+
437+ ** Importante:** Non chiamare ` refreshSession() ` ad ogni richiesta per evitare ` AuthApiError: Request rate limit reached ` .
438+
402439---
403440
404441## 6. CI/CD Pipeline
@@ -657,15 +694,36 @@ Sentry.init({
657694});
658695```
659696
660- ** Mobile App** (` apps/mobile/src/lib/sentry.ts ` ):
697+ ** Mobile App** (` apps/mobile/app/_layout.tsx ` ):
661698``` typescript
662699import * as Sentry from " @sentry/react-native" ;
663700
664- Sentry .init ({
665- dsn: process .env .EXPO_PUBLIC_SENTRY_DSN ,
666- environment: __DEV__ ? " development" : " production" ,
667- tracesSampleRate: 0.1 ,
668- });
701+ const SENTRY_DSN = process .env .EXPO_PUBLIC_SENTRY_DSN ;
702+
703+ if (SENTRY_DSN ) {
704+ Sentry .init ({
705+ dsn: SENTRY_DSN ,
706+ debug: __DEV__ ,
707+ environment: __DEV__ ? " development" : " production" ,
708+ tracesSampleRate: 1.0 ,
709+ });
710+ }
711+
712+ // Wrap root component with Sentry error boundary
713+ export default Sentry .wrap (RootLayout );
714+ ```
715+
716+ ** Plugin Expo** (` app.json ` ):
717+ ``` json
718+ {
719+ "plugins" : [
720+ " expo-router" ,
721+ [" @sentry/react-native/expo" , {
722+ "organization" : " lumio" ,
723+ "project" : " lumio-mobile"
724+ }]
725+ ]
726+ }
669727```
670728
671729** Edge Functions** :
@@ -754,7 +812,10 @@ openssl rand -base64 32
754812| ----------| -------------|
755813| ` EXPO_PUBLIC_SUPABASE_URL ` | Supabase project URL |
756814| ` EXPO_PUBLIC_SUPABASE_ANON_KEY ` | Supabase anonymous key |
757- | ` EXPO_PUBLIC_SENTRY_DSN ` | Sentry DSN |
815+ | ` EXPO_PUBLIC_SENTRY_DSN ` | Sentry DSN per crash reporting |
816+
817+ ** Nota:** Le variabili sono configurate in ` eas.json ` per profile ` preview ` e ` production ` .
818+ Il DSN Sentry viene passato come env var durante il build EAS.
758819
759820### 12.3 Edge Functions
760821
0 commit comments