{"nodes": [{"id": "plan_fase_1", "label": "Fase 1 \u2014 Autenticaci\u00f3n y Colectivo", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "concept_keycloak_gotrue_oidc_proxy", "label": "GoTrue as OIDC proxy for Keycloak (Option B auth strategy)", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.2", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "concept_paraglide_i18n", "label": "Paraglide JS i18n (@inlang/paraglide-sveltekit, compile-time tree-shaken)", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.4", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "concept_invitations_link_only", "label": "Link-only invitations (no email, token URL shared manually)", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.3", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "concept_rls_policies", "label": "Row-Level Security across all public tables (is_active_member / is_admin helpers)", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.1", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "rationale_option_b_gotrue_proxy", "label": "Why Option B (GoTrue as OIDC proxy): keeps auth.users populated, lets RLS use auth.uid(), allows GoTrue helpers", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.2", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "rationale_no_email_invitations", "label": "Why no-email invitations: avoids Resend setup for MVP; link via any channel", "file_type": "document", "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.3", "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "plan_fase_1", "target": "plan_fase_0", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": null, "weight": 1.0}, {"source": "plan_fase_1", "target": "concept_keycloak_gotrue_oidc_proxy", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.2", "weight": 1.0}, {"source": "plan_fase_1", "target": "concept_paraglide_i18n", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.4", "weight": 1.0}, {"source": "plan_fase_1", "target": "concept_invitations_link_only", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.3", "weight": 1.0}, {"source": "plan_fase_1", "target": "concept_rls_policies", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.1", "weight": 1.0}, {"source": "rationale_option_b_gotrue_proxy", "target": "concept_keycloak_gotrue_oidc_proxy", "relation": "rationale_for", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.2", "weight": 1.0}, {"source": "rationale_no_email_invitations", "target": "concept_invitations_link_only", "relation": "rationale_for", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "plan/fase-1-auth-colectivo.md", "source_location": "\u00a71.3", "weight": 1.0}], "hyperedges": []}