1 line
49 KiB
JSON
1 line
49 KiB
JSON
{"repo": "achrafbenyounes/nexus-data-fabric", "files": {"components/manual_tab.py": {"c0d23d06760a0a4332544285f96fd86ec9264a74": {"t": 1785596429.5037189, "n": 47220, "h": "04164af362274ef7", "c": "import streamlit as st\n\nMANUAL_CONTENT = {\n \"fr\": {\n \"intro\": {\n \"title\": \"1. Introduction à NEXUS Data Fabric\",\n \"content\": \"\"\"\nNEXUS Data Fabric est une plateforme **open-source** de conception de pipelines data, pensée pour les équipes data engineering modernes. Elle unifie dans une seule interface :\n\n- Le design visuel de pipelines **batch et streaming**\n- L'exécution sur **Apache Spark** (Python, Scala, Java)\n- L'intégration native avec **Databricks**, **Snowflake** et les 3 grands clouds\n- Un **AI Co-pilot** qui génère des configurations depuis le langage naturel\n- La gestion de la **qualité de données**, du **lineage** et des **data contracts**\n\n### Pourquoi NEXUS ?\n\n| Problème courant | Solution NEXUS |\n|---|---|\n| 4 outils, 4 interfaces, 4 monitorings | Un canvas unique, une observabilité unifiée |\n| Logique batch et streaming dupliquée | Kappa Architecture native |\n| Lineage partiel ou inexistant | Lineage colonne-à-colonne automatique |\n| Secrets hardcodés | Vault + rotation automatique |\n| Backfill manuel et risqué | Smart Backfill par IA |\n\n### Architecture générale\n\n```\nSources ──► [NEXUS Canvas] ──► Transforms ──► Sinks\n │\n ┌───────┴────────┐\n │ Orchestrateur │ ← Airflow-compatible\n │ AI Co-pilot │ ← LLM génératif\n │ DQ + Lineage │ ← Great Expectations\n │ Secrets Vault │ ← HashiCorp Vault\n └────────────────┘\n```\n\"\"\",\n },\n \"quickstart\": {\n \"title\": \"2. Démarrage rapide\",\n \"content\": \"\"\"\n### Installation locale\n\n```bash\n# Cloner le dépôt\ngit clone https://github.com/nexus-data/nexus-platform.git\ncd nexus-platform\n\n# Avec Docker Compose (recommandé)\ndocker compose up -d\n\n# Accès à l'UI\nopen http://localhost:8501\n```\n\n### Premier pipeline en 5 minutes\n\n**Étape 1 — Configurer un connecteur**\n\nAllez dans l'onglet `🔌 Connecteurs`, sélectionnez votre source (ex : PostgreSQL), remplissez les champs et cliquez **Tester la connexion**, puis **Sauvegarder**.\n\n**Étape 2 — Ouvrir le canvas**\n\nAllez dans l'onglet `🎨 Pipeline Canvas`. Donnez un nom à votre pipeline et choisissez le mode (Batch / Streaming / Hybride).\n\n**Étape 3 — Ajouter des nœuds**\n\nDans le panneau gauche, chaque type de nœud affiche des champs de configuration dynamiques :\n\n1. `Source` → `PostgreSQL` → remplissez **Schéma** et **Table / Query** → nommez-le → **Ajouter**\n2. `Transform` → `dbt SQL` → choisissez l'**Opération** (ex : Mart Model) → choisissez la **Matérialisation** → nommez-le → **Ajouter**\n3. `Sink` → `Snowflake` → remplissez **Database**, **Schema**, **Table** → choisissez le **Write Mode** → nommez-le → **Ajouter**\n\nLe canvas valide la structure en temps réel : un bandeau ✅ confirme que le pipeline possède au moins une Source et un Sink.\n\n**Étape 4 — Exporter et déployer**\n\nCliquez sur **Exporter YAML**. Le fichier généré inclut toute la configuration de chaque nœud et est compatible avec le scheduler NEXUS et Apache Airflow.\n\n```yaml\npipeline:\n name: mon-premier-pipeline\n mode: batch\n schedule: \"0 6 * * *\"\n nodes:\n - id: src_01\n type: Source\n connector: PostgreSQL\n dq_enabled: false\n config:\n Schema: public\n \"Table / Query\": orders\n - id: tr_01\n type: Transform\n connector: dbt SQL\n dq_enabled: true\n config:\n operation: Mart Model\n materialization: table\n dbt_target_profile: snowflake_prod\n threads: \"8\"\n - id: snk_01\n type: Sink\n connector: Snowflake\n dq_enabled: false\n config:\n Database: ANALYTICS\n Schema: MARTS\n Table: REVENUE_BY_REGION\n \"Write Mode\": overwrite\n```\n\n**Étape 5 — Monitorer**\n\nLe dashboard d'observabilité NEXUS (Grafana + OpenTelemetry) se lance automatiquement sur `http://localhost:3000`.\n\"\"\",\n },\n \"canvas\": {\n \"title\": \"3. Pipeline Canvas\",\n \"content\": \"\"\"\n### Vue d'ensemble\n\nLe Pipeline Canvas est le cœur de NEXUS. C'est une interface **low-code drag & drop** qui permet de concevoir des pipelines data complexes sans écrire de code d'infrastructure.\n\nLe panneau gauche construit le pipeline nœud par nœud ; le panneau droit affiche l'aperçu visuel en temps réel avec validation, et génère le YAML/JSON exportable.\n\n---\n\n### Types de nœuds\n\n#### 🔵 Source — Configuration dynamique\n\nLorsque vous sélectionnez un connecteur Source, un panneau **📥 Source configuration** apparaît avec les champs adaptés :\n\n| Connecteur | Champs disponibles |\n|---|---|\n| Kafka | Topic · Consumer Group · Format (JSON/Avro/Protobuf/CSV) · Offset (latest/earliest/timestamp) |\n| S3 / GCS / Azure Blob | Bucket/Path · Format (Parquet/CSV/JSON/ORC/Delta) · Partition Filter |\n| PostgreSQL / MySQL / Oracle / Redshift | Schema · Table / Query |\n| Snowflake / Databricks | Database · Schema · Table |\n| Google BigQuery | Dataset · Table |\n| MongoDB | Database · Collection · Filter Query |\n| REST API | Endpoint URL · HTTP Method · Auth (Bearer/API Key/OAuth2) |\n| SFTP | Remote Path · File Pattern · Format |\n\n#### 🟢 Transform — Opérations et configuration\n\nChaque connecteur Transform expose un sélecteur **🔧 Transformation Operation** contextuel, puis des options avancées dans un panneau **⚙️ Additional configuration** :\n\n| Connecteur | Opérations disponibles | Options avancées |\n|---|---|---|\n| **dbt SQL** | Staging Model · Intermediate Model · Mart Model · Snapshot · Test Suite | Materialization (table/view/incremental/ephemeral) · dbt Target Profile · Threads |\n| **Spark Python** | Filter & Clean · Join · Aggregate & Group By · Window Function · Deduplication · Feature Engineering · ML Training · ML Inference · Delta Merge (UPSERT) · Custom Logic | Spark Template (ETL/Streaming/ML Pipeline/Delta Lake) |\n| **Spark Scala** | Filter & Clean · Join · Aggregate · Window Function · Dedup · Delta Merge · ML Training · Custom | Spark Template |\n| **Spark Java** | Filter & Clean · Join · Aggregate · Window Function · Dedup · Delta Merge · Custom | Spark Template |\n| **Flink Job** | Tumbling Window · Sliding Window · Session Window · CEP Pattern Matching · Stateful Map/FlatMap · Async IO Enrichment · Table API Join | Window Size · Parallelism |\n| **Python UDF** | Map · Filter · FlatMap · Aggregate · Custom Python | Function Name |\n| **SQL Window** | ROW_NUMBER · RANK · DENSE_RANK · LAG · LEAD · SUM OVER · AVG OVER · COUNT OVER · NTILE · FIRST_VALUE/LAST_VALUE | Partition By · Order By |\n| **AI Enrich** | Text Enrichment · Entity Extraction (NER) · Sentiment Analysis · Classification · Translation · Summarization · Custom Prompt | LLM Model (Claude/GPT-4o/Mistral/Llama) · Input Columns · Output Column |\n| **ML Inference** | Binary Classification · Multi-class Classification · Regression · Clustering · Anomaly Detection · Recommendation · Time-Series Forecast | Model Path/URI · Feature Columns · Prediction Column |\n| **Data Masking** | Hash SHA-256 · Tokenize · Nullify · Format-Preserving Encryption · Pseudonymize · Redact (→ ***) · Generalize | Columns to Mask |\n| **Schema Validate** | Strict Validation · Lenient Validation · Drift Detection · Schema Registry Check · Data Contract Validation | Schema Source (Inline/Confluent/AWS Glue/S3) |\n| **Dedup** | Exact Dedup · Key-based (Keep First/Last/Max) · Fuzzy Dedup · Streaming Dedup | Dedup Key Columns |\n\nPour les connecteurs Spark (Python / Scala / Java), un sélecteur **Spark Language** apparaît également.\n\n#### 🔴 Sink — Configuration dynamique\n\nLorsque vous sélectionnez un connecteur Sink, un panneau **📤 Sink configuration** apparaît :\n\n| Connecteur | Champs disponibles |\n|---|---|\n| Snowflake | Database · Schema · Table · Write Mode (append/overwrite/merge) |\n| BigQuery | Dataset · Table · Write Mode |\n| Redshift / PostgreSQL | Schema · Table · Write Mode (append/upsert/overwrite) |\n| ClickHouse | Table · Engine (MergeTree/ReplacingMergeTree/AggregatingMergeTree) · Write Mode |\n| Databricks Delta | Catalog · Schema · Table · Write Mode · Merge Keys · Z-Order By |\n| S3 | Bucket/Path · Format · Partition By |\n| Kafka Topic | Topic · Format (JSON/Avro/Protobuf) |\n| Redis | Key Pattern (ex : `user:{id}`) · TTL (secondes) |\n| Elasticsearch | Index · ID Field |\n| Slack Alert | Channel · Message Template · Trigger Condition |\n| PagerDuty | Severity (critical/error/warning/info) · Filter Condition |\n\n---\n\n### Validation structurelle en temps réel\n\nLe canvas analyse le pipeline à chaque ajout de nœud et affiche un bandeau :\n\n- **✅ Structure du pipeline valide** — au moins une Source et un Sink sont présents\n- **⚠️ Pipeline sans nœud Source** — ajoutez une source de données\n- **⚠️ Pipeline sans nœud Sink** — ajoutez une destination\n\n---\n\n### Gestion des nœuds\n\nChaque nœud dans l'aperçu affiche :\n- L'**icône** de type (🔵 Source / 🟢 Transform / 🔴 Sink)\n- Le **nom** du nœud\n- Le connecteur entre crochets\n- Un badge **⚙ opération** pour les transforms (ex : `⚙ Mart Model`)\n- Un badge **Spark Language** si applicable\n- Un badge vert **DQ ✓** si les contrôles qualité sont activés\n- Un hint en italique avec la première valeur de configuration renseignée\n- Un bouton **✕** pour supprimer le nœud individuellement sans réinitialiser tout le pipeline\n\n---\n\n### Modes d'exécution\n\n**Batch** : Traitement planifié (cron), idéal pour les ETL quotidiens, les rapports, les exports.\n\n**Streaming** : Traitement en temps réel (< 1 seconde à quelques minutes de latence), idéal pour la détection de fraude, le monitoring, les recommandations.\n\n**Hybride** : NEXUS gère automatiquement la transition batch → streaming selon le volume et la latence cible. Un schedule cron est requis pour la composante batch.\n\n---\n\n### Data Quality intégrée\n\nChaque nœud Transform peut activer des contrôles DQ via la checkbox **Data Quality checks** :\n\n```yaml\ntransform:\n name: tr_dbt_revenue\n dq_enabled: true\n dq_checks:\n - type: not_null\n columns: [user_id, event_type]\n - type: unique\n columns: [event_id]\n - type: row_count_gte\n value: 1000\n - type: custom_sql\n query: \"SELECT COUNT(*) FROM {{ table }} WHERE amount < 0\"\n expect: 0\n```\n\nSi un contrôle échoue, le pipeline est mis en quarantaine et une alerte est envoyée.\n\n---\n\n### Export YAML / JSON enrichi\n\nLe pipeline exporté contient maintenant le bloc `config:` complet de chaque nœud, avec toutes les options renseignées dans l'interface. Exemple complet :\n\n```yaml\npipeline:\n name: kafka-dbt-snowflake\n mode: batch\n schedule: 0 6 * * *\n version: '1.0'\n nodes:\n - id: src_01\n name: source_kafka_events\n type: Source\n connector: Kafka\n dq_enabled: false\n config:\n Topic: nexus.events\n Consumer Group: nexus-consumer\n Format: JSON\n Offset: latest\n\n - id: tr_01\n name: transform_dbt_revenue\n type: Transform\n connector: dbt SQL\n dq_enabled: true\n config:\n operation: Mart Model\n materialization: incremental\n dbt_target_profile: snowflake_prod\n threads: '8'\n\n - id: snk_01\n name: sink_snowflake_analytics\n type: Sink\n connector: Snowflake\n dq_enabled: false\n config:\n Database: ANALYTICS\n Schema: MARTS\n Table: REVENUE_BY_REGION\n Write Mode: overwrite\n```\n\nLe fichier généré est versionnable en Git et déployable avec :\n```bash\nnexus pipeline deploy --file kafka-dbt-snowflake.yaml --env prod\n```\n\"\"\",\n },\n \"spark\": {\n \"title\": \"4. Support Apache Spark\",\n \"content\": \"\"\"\n### Langages supportés\n\nNEXUS génère du code Spark natif en **Python (PySpark)**, **Scala** et **Java**. Le générateur de code s'adapte au template choisi.\n\n### Templates disponibles\n\n#### ETL basique\nPipeline d'extraction → transformation → chargement. Inclut :\n- Lecture depuis S3 (format Parquet)\n- Nettoyage et déduplication\n- Data Quality via assertions\n- Écriture partitionnée vers la destination\n\n#### Streaming Kafka\nPipeline de consommation Kafka avec Spark Structured Streaming. Inclut :\n- Lecture depuis un topic Kafka avec gestion des offsets\n- Fenêtrage temporel (window / watermark)\n- Agrégations en temps réel\n- Écriture vers ClickHouse ou tout sink JDBC\n\n#### ML Pipeline\nPipeline d'entraînement et d'inférence Spark MLlib. Inclut :\n- Feature engineering (VectorAssembler, StandardScaler)\n- Entraînement avec validation croisée\n- Sélection du meilleur modèle\n- Sauvegarde du modèle sur S3\n\n#### Delta Lake\nPipeline de gestion de tables Delta Lake. Inclut :\n- Lecture du staging\n- MERGE (UPSERT) intelligent\n- OPTIMIZE + Z-ORDER pour les performances\n- VACUUM pour la gestion de la rétention\n\n### Configuration Spark recommandée\n\n| Workload | Exécuteurs | Mémoire/exec | Cœurs/exec |\n|---|---|---|---|\n| ETL standard | 4–8 | 4g | 2 |\n| Streaming | 2–4 | 2g | 2 |\n| ML training | 8–16 | 8g | 4 |\n| Delta MERGE | 4–8 | 4g | 2 |\n\n### Modes d'exécution Spark\n\n**Local** (`local[*]`) : Pour le développement et les tests. Pas de cluster requis.\n\n**YARN** : Pour les clusters Hadoop on-premise ou EMR.\n\n**Kubernetes** : Pour les déploiements cloud-native. NEXUS génère le Helm chart.\n\n**Databricks** : Utilise l'API Databricks Jobs API. NEXUS gère le cycle de vie du cluster.\n\n### Intégration Databricks\n\n```python\nfrom databricks.sdk import WorkspaceClient\n\nw = WorkspaceClient(\n host = \"https://adb-xxx.azuredatabricks.net\",\n token = os.environ[\"DATABRICKS_TOKEN\"]\n)\n\n# Soumettre un job via NEXUS\njob = w.jobs.submit(\n run_name = \"nexus-job-run\",\n tasks = [{\"task_key\": \"etl\", \"spark_python_task\": {\n \"python_file\": \"dbfs:/nexus/jobs/my_etl.py\"\n }}]\n)\n```\n\"\"\",\n },\n \"connectors\": {\n \"title\": \"5. Connecteurs\",\n \"content\": \"\"\"\n### Architecture des connecteurs\n\nChaque connecteur NEXUS est un plugin Python qui implémente l'interface `NexusConnector` :\n\n```python\nfrom nexus.connectors import NexusConnector\n\nclass SnowflakeConnector(NexusConnector):\n def read(self, spark, config) -> DataFrame:\n return spark.read.format(\"snowflake\").options(**config).load()\n\n def write(self, df, config, mode=\"overwrite\"):\n df.write.format(\"snowflake\").options(**config).mode(mode).save()\n\n def test_connection(self, config) -> bool:\n # Vérifie les credentials\n ...\n```\n\n### Snowflake\n\n**Prérequis** : compte Snowflake, warehouse actif, rôle avec permissions `USAGE` et `SELECT`.\n\n**Variables d'environnement recommandées** :\n```bash\nNEXUS_SF_ACCOUNT=myorg-myaccount\nNEXUS_SF_USER=my_user\nNEXUS_SF_PASSWORD=**** # ou private key\nNEXUS_SF_WAREHOUSE=COMPUTE_WH\nNEXUS_SF_DATABASE=NEXUS_DB\nNEXUS_SF_SCHEMA=PUBLIC\n```\n\n**Modes d'authentification** : Password, Key Pair (RSA), OAuth 2.0, SSO (SAML).\n\n### Databricks — Types d'abonnement et capacités\n\nNEXUS supporte **tous les types** d'abonnement Databricks. Choisissez votre type dans\nl'onglet Connecteurs → Databricks → colonne « Type d'abonnement ». Les champs s'adaptent automatiquement.\n\n| Type | Unity Catalog | SQL Warehouse | Service Principal | Identity Provider | URL pattern | Notes |\n|---|:---:|:---:|:---:|---|---|---|\n| 🆓 Free / Community Edition | ⚠️ limité | ✅ (1 small) | ❌ | none | `community.cloud.databricks.com` | Usage perso uniquement, très limité |\n| ☁️ AWS Standard | ❌ | ✅ | ❌ | AWS IAM / external SSO | `<workspace>.cloud.databricks.com` | Pas d'UC, gouvernance limitée |\n| ☁️ AWS Premium / Enterprise | ✅ | ✅ | ✅ | AWS IAM / external SSO | `<workspace>.cloud.databricks.com` | Production ready, gouvernance complète |\n| 🔷 Azure Standard | ❌ | ✅ | ❌ | Azure AD | `adb-<id>.<region>.azuredatabricks.net` | Intégré Azure AD |\n| 🔷 Azure Premium / Enterprise | ✅ | ✅ | ✅ | Azure AD | `adb-<id>.<region>.azuredatabricks.net` | Sécurité & gouvernance enterprise |\n| 🟡 GCP Standard | ❌ | ✅ | ❌ | Google IAM / Identity | `<workspace>.gcp.databricks.com` | Gouvernance limitée |\n| 🟡 GCP Premium / Enterprise | ✅ | ✅ | ✅ | Google IAM / Identity | `<workspace>.gcp.databricks.com` | Production ready |\n\n> ⚠️ **Azure Databricks Standard** : Unity Catalog non supporté et pas de Service Principal.\n> L'intégration Azure AD est disponible. Les tables sont dans `hive_metastore`.\n> Passez en **Premium ou Enterprise** pour Unity Catalog.\n\n**Méthodes d'authentification disponibles selon le type :**\n- **PAT (Personal Access Token)** : disponible sur tous les types.\n- **Azure AAD (Bearer token)** : Azure uniquement. Générez via `az account get-access-token`.\n- **Service Principal / OAuth M2M** : AWS Premium, Azure Premium, GCP Premium.\n\n**3 connecteurs Databricks simultanés** : NEXUS permet de configurer jusqu'à 3 connecteurs\nDatabricks indépendants (ex : Production AWS, Staging Azure, Dev Community). Dans le Pipeline Canvas,\nun sélecteur apparaît si plusieurs connecteurs sont configurés.\n\n**Prérequis** : workspace Databricks, cluster All-Purpose ou Job Cluster, Personal Access Token (ou AAD/SP selon le type).\n\n**Unity Catalog** : NEXUS supporte nativement Unity Catalog pour la gouvernance des données et le lineage cross-workspace. Sur les types sans Unity Catalog, le browser navigue dans `hive_metastore`.\n\n### Gestion des secrets\n\nNEXUS ne stocke jamais les credentials en clair. Toutes les connexions passent par le **Vault NEXUS** :\n\n```yaml\n# secrets.yaml (chiffré AES-256)\nnexus_secrets:\n snowflake_password:\n vault_path: secret/nexus/snowflake\n rotation: 90d\n databricks_token:\n vault_path: secret/nexus/databricks\n rotation: 30d\n```\n\n### Création d'un connecteur custom\n\n```bash\nnexus connector new --name my-custom-connector\n# Génère le squelette dans ./connectors/my_custom_connector/\n```\n\"\"\",\n },\n \"copilot\": {\n \"title\": \"6. AI Co-pilot\",\n \"content\": \"\"\"\n### Fonctionnement\n\nLe Co-pilot NEXUS est un assistant IA spécialisé dans la conception de pipelines data. Il comprend :\n\n- La topologie de vos connecteurs configurés\n- Vos contraintes SLA et de coût\n- Les patterns de pipelines courants (ETL, CDC, ML, alerting)\n- Les bonnes pratiques Spark et streaming\n\n### Exemples d'utilisation\n\n**Génération de pipeline**\n```\nUtilisateur : \"Crée un pipeline qui lit les commandes de PostgreSQL,\n calcule le CA par région avec dbt, et charge dans Snowflake\n tous les jours à 6h du matin.\"\n\nCo-pilot : ✅ Pipeline généré :\n - Source : PostgreSQL → table orders\n - Transform : dbt SQL → model revenue_by_region\n - Sink : Snowflake → table ANALYTICS.REVENUE\n - Schedule : 0 6 * * * (UTC)\n - SLA estimé : ~45 min\n```\n\n**Optimisation**\n```\nUtilisateur : \"Mon job Spark prend 3h, comment l'optimiser ?\"\n\nCo-pilot : J'analyse votre configuration...\n 1. Activez spark.sql.adaptive.enabled=true\n 2. Réduisez spark.default.parallelism à 200\n 3. Ajoutez .repartition(\"event_date\") avant l'écriture\n 4. Activez la compression Snappy : parquet.compression=SNAPPY\n → Gain estimé : -60% sur le temps d'exécution\n```\n\n**Débogage**\n```\nUtilisateur : \"Mon pipeline échoue avec OOM sur l'executor\"\n\nCo-pilot : Probable cause : shuffle de données déséquilibré.\n Solutions :\n 1. spark.executor.memory=8g (actuellement 4g)\n 2. spark.sql.shuffle.partitions=400\n 3. Vérifiez les skews avec df.groupBy(\"partition_col\").count()\n```\n\n### Modèles LLM supportés\n\n| Modèle | Usage | Latence |\n|---|---|---|\n| GPT-4o | Génération complexe | ~3s |\n| Claude 3.5 Sonnet | Génération + optimisation | ~2s |\n| Llama 3.1 (local) | Air-gapped / données sensibles | ~8s |\n| Mistral Large | Génération standard | ~2s |\n\n### Configuration\n\n```yaml\n# nexus.yaml\ncopilot:\n provider: anthropic # openai | anthropic | ollama | mistral\n model: claude-3-5-sonnet # selon le provider\n max_tokens: 4096\n context_window: pipelines + connectors + metrics\n data_privacy: true # anonymise les noms avant envoi au LLM\n```\n\"\"\",\n },\n \"deployment\": {\n \"title\": \"7. Déploiement\",\n \"content\": \"\"\"\n### Streamlit Cloud (recommandé pour débuter)\n\n```bash\n# 1. Forker le repo NEXUS sur GitHub\n# 2. Aller sur share.streamlit.io\n# 3. Connecter votre repo\n# 4. Configurer les secrets dans Settings → Secrets :\n\n[secrets]\nOPENAI_API_KEY = \"sk-...\"\nSNOWFLAKE_PASSWORD = \"****\"\nDATABRICKS_TOKEN = \"dapi...\"\n```\n\n### Docker Compose (développement)\n\n```yaml\n# docker-compose.yaml\nservices:\n nexus-ui:\n image: nexusdata/platform:latest\n ports: [\"8501:8501\"]\n environment:\n - NEXUS_SECRET_KEY=${SECRET_KEY}\n volumes:\n - ./pipelines:/app/pipelines\n\n nexus-scheduler:\n image: nexusdata/scheduler:latest\n depends_on: [postgres, redis]\n\n postgres:\n image: postgres:15-alpine\n environment:\n POSTGRES_DB: nexus_meta\n\n redis:\n image: redis:7-alpine\n```\n\n### Kubernetes (production)\n\n```bash\n# Via Helm Chart NEXUS\nhelm repo add nexus https://charts.nexusdata.io\nhelm install nexus nexus/nexus-platform \\\\\n --namespace nexus \\\\\n --set global.cloud=gcp \\\\\n --set spark.mode=kubernetes \\\\\n --set vault.enabled=true\n```\n\n### Variables d'environnement importantes\n\n| Variable | Description | Requis |\n|---|---|---|\n| `NEXUS_SECRET_KEY` | Clé de chiffrement interne | ✅ |\n| `NEXUS_VAULT_ADDR` | URL HashiCorp Vault | Production |\n| `NEXUS_DB_URL` | PostgreSQL pour les métadonnées | ✅ |\n| `NEXUS_REDIS_URL` | Redis pour le cache | ✅ |\n| `NEXUS_LOG_LEVEL` | DEBUG / INFO / WARN | Non |\n\"\"\",\n },\n \"best_practices\": {\n \"title\": \"8. Bonnes pratiques\",\n \"content\": \"\"\"\n### Design de pipelines\n\n**✅ À faire**\n- Un pipeline = une responsabilité unique (principe SRP)\n- Nommer les nœuds de façon descriptive : `src_postgres_orders`, `tr_dbt_revenue`, `snk_snowflake_analytics`\n- Versionner tous les pipelines YAML en Git\n- Définir un SLA par pipeline et configurer les alertes correspondantes\n- Activer la Data Quality sur chaque Transform\n- Utiliser des Data Contracts entre producteurs et consommateurs\n\n**❌ À éviter**\n- Pipelines \"catch-all\" qui font tout (extraction + ML + reporting)\n- Secrets en dur dans la configuration YAML\n- Ignorer les erreurs OOM Spark sans investiguer le skew\n- Désactiver les contrôles DQ en production\n\n### Spark\n\n```python\n# ✅ Bonne pratique : adaptive query execution\nspark.conf.set(\"spark.sql.adaptive.enabled\", \"true\")\nspark.conf.set(\"spark.sql.adaptive.coalescePartitions.enabled\", \"true\")\n\n# ✅ Bonne pratique : partitionner avant l'écriture\ndf.repartition(col(\"event_date\")).write.partitionBy(\"event_date\").parquet(...)\n\n# ✅ Bonne pratique : cache les DataFrames réutilisés\ndf_clean.cache()\ndf_clean.count() # force le cache\n\n# ❌ Mauvaise pratique : collect() sur un grand DataFrame\nall_rows = df.collect() # OOM garanti sur un gros dataset\n```\n\n### Streaming\n\n- Toujours définir un **watermark** pour les late arrivals\n- Configurer le **checkpointing** sur un stockage durable (S3, HDFS)\n- Surveiller le **lag Kafka** (objectif : < 10 000 messages)\n- Utiliser `processingTime` trigger plutôt que `once` en production\n\n### Sécurité\n\n- Activer le **RBAC NEXUS** : chaque équipe voit uniquement ses pipelines\n- Utiliser des **Service Accounts** dédiés par pipeline (principe du moindre privilège)\n- Auditer les accès aux données sensibles via le log NEXUS\n- Appliquer le **Data Masking** automatique sur les colonnes PII\n\n### Coût cloud\n\n| Levier | Économie potentielle |\n|---|---|\n| Spot Instances pour les jobs Spark batch | 60–80% |\n| Autoscaling Databricks (min/max workers) | 40–60% |\n| Compression Parquet + Z-ORDER ClickHouse | 30–50% I/O |\n| Partition pruning bien configuré | 20–40% scan |\n\"\"\",\n },\n },\n\n \"en\": {\n \"intro\": {\n \"title\": \"1. Introduction to NEXUS Data Fabric\",\n \"content\": \"\"\"\nNEXUS Data Fabric is an **open-source** data pipeline design platform built for modern data engineering teams. It unifies in a single interface:\n\n- Visual **batch and streaming** pipeline design\n- Execution on **Apache Spark** (Python, Scala, Java)\n- Native integration with **Databricks**, **Snowflake** and all 3 major clouds\n- An **AI Co-pilot** that generates configurations from natural language\n- **Data quality**, **lineage** and **data contracts** management\n\n### Why NEXUS?\n\n| Current pain | NEXUS solution |\n|---|---|\n| 4 tools, 4 interfaces, 4 monitoring stacks | Single canvas, unified observability |\n| Duplicated batch and streaming logic | Native Kappa Architecture |\n| Partial or missing lineage | Automatic column-level lineage |\n| Hardcoded secrets | Vault + automatic rotation |\n| Manual, risky backfills | AI-powered Smart Backfill |\n\n### General architecture\n\n```\nSources ──► [NEXUS Canvas] ──► Transforms ──► Sinks\n │\n ┌───────┴────────┐\n │ Orchestrator │ ← Airflow-compatible\n │ AI Co-pilot │ ← Generative LLM\n │ DQ + Lineage │ ← Great Expectations\n │ Secrets Vault │ ← HashiCorp Vault\n └────────────────┘\n```\n\"\"\",\n },\n \"quickstart\": {\n \"title\": \"2. Quick start\",\n \"content\": \"\"\"\n### Local installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/nexus-data/nexus-platform.git\ncd nexus-platform\n\n# With Docker Compose (recommended)\ndocker compose up -d\n\n# Access the UI\nopen http://localhost:8501\n```\n\n### First pipeline in 5 minutes\n\n**Step 1 — Configure a connector**\n\nGo to the `🔌 Connectors` tab, select your source (e.g. PostgreSQL), fill in the fields and click **Test connection**, then **Save**.\n\n**Step 2 — Open the canvas**\n\nGo to the `🎨 Pipeline Canvas` tab. Give your pipeline a name and choose the mode (Batch / Streaming / Hybrid).\n\n**Step 3 — Add nodes**\n\nIn the left panel, each node type shows dynamic configuration fields:\n\n1. `Source` → `PostgreSQL` → fill in **Schema** and **Table / Query** → name it → **Add**\n2. `Transform` → `dbt SQL` → choose the **Operation** (e.g. Mart Model) → choose **Materialization** → name it → **Add**\n3. `Sink` → `Snowflake` → fill in **Database**, **Schema**, **Table** → choose **Write Mode** → name it → **Add**\n\nThe canvas validates the structure in real time: a ✅ banner confirms the pipeline has at least one Source and one Sink.\n\n**Step 4 — Export and deploy**\n\nClick **Export YAML**. The generated file includes the full configuration of each node and is compatible with the NEXUS scheduler and Apache Airflow.\n\n```yaml\npipeline:\n name: my-first-pipeline\n mode: batch\n schedule: \"0 6 * * *\"\n nodes:\n - id: src_01\n type: Source\n connector: PostgreSQL\n dq_enabled: false\n config:\n Schema: public\n \"Table / Query\": orders\n - id: tr_01\n type: Transform\n connector: dbt SQL\n dq_enabled: true\n config:\n operation: Mart Model\n materialization: table\n dbt_target_profile: snowflake_prod\n threads: \"8\"\n - id: snk_01\n type: Sink\n connector: Snowflake\n dq_enabled: false\n config:\n Database: ANALYTICS\n Schema: MARTS\n Table: REVENUE_BY_REGION\n \"Write Mode\": overwrite\n```\n\n**Step 5 — Monitor**\n\nThe NEXUS observability dashboard (Grafana + OpenTelemetry) starts automatically at `http://localhost:3000`.\n\"\"\",\n },\n \"canvas\": {\n \"title\": \"3. Pipeline Canvas\",\n \"content\": \"\"\"\n### Overview\n\nThe Pipeline Canvas is the heart of NEXUS. It is a **low-code drag & drop** interface that allows you to design complex data pipelines without writing infrastructure code.\n\nThe left panel builds the pipeline node by node; the right panel shows the live visual preview with validation and generates the exportable YAML/JSON.\n\n---\n\n### Node types\n\n#### 🔵 Source — Dynamic configuration\n\nWhen you select a Source connector, a **📥 Source configuration** panel appears with the relevant fields:\n\n| Connector | Available fields |\n|---|---|\n| Kafka | Topic · Consumer Group · Format (JSON/Avro/Protobuf/CSV) · Offset (latest/earliest/timestamp) |\n| S3 / GCS / Azure Blob | Bucket/Path · Format (Parquet/CSV/JSON/ORC/Delta) · Partition Filter |\n| PostgreSQL / MySQL / Oracle / Redshift | Schema · Table / Query |\n| Snowflake / Databricks | Database · Schema · Table |\n| Google BigQuery | Dataset · Table |\n| MongoDB | Database · Collection · Filter Query |\n| REST API | Endpoint URL · HTTP Method · Auth (Bearer/API Key/OAuth2) |\n| SFTP | Remote Path · File Pattern · Format |\n\n#### 🟢 Transform — Operations and configuration\n\nEach Transform connector exposes a contextual **🔧 Transformation Operation** selector, then advanced options in an **⚙️ Additional configuration** panel:\n\n| Connector | Available operations | Advanced options |\n|---|---|---|\n| **dbt SQL** | Staging Model · Intermediate Model · Mart Model · Snapshot · Test Suite | Materialization (table/view/incremental/ephemeral) · dbt Target Profile · Threads |\n| **Spark Python** | Filter & Clean · Join · Aggregate & Group By · Window Function · Deduplication · Feature Engineering · ML Training · ML Inference · Delta Merge (UPSERT) · Custom Logic | Spark Template (ETL/Streaming/ML Pipeline/Delta Lake) |\n| **Spark Scala** | Filter & Clean · Join · Aggregate · Window Function · Dedup · Delta Merge · ML Training · Custom | Spark Template |\n| **Spark Java** | Filter & Clean · Join · Aggregate · Window Function · Dedup · Delta Merge · Custom | Spark Template |\n| **Flink Job** | Tumbling Window · Sliding Window · Session Window · CEP Pattern Matching · Stateful Map/FlatMap · Async IO Enrichment · Table API Join | Window Size · Parallelism |\n| **Python UDF** | Map · Filter · FlatMap · Aggregate · Custom Python | Function Name |\n| **SQL Window** | ROW_NUMBER · RANK · DENSE_RANK · LAG · LEAD · SUM OVER · AVG OVER · COUNT OVER · NTILE · FIRST_VALUE/LAST_VALUE | Partition By · Order By |\n| **AI Enrich** | Text Enrichment · Entity Extraction (NER) · Sentiment Analysis · Classification · Translation · Summarization · Custom Prompt | LLM Model (Claude/GPT-4o/Mistral/Llama) · Input Columns · Output Column |\n| **ML Inference** | Binary Classification · Multi-class Classification · Regression · Clustering · Anomaly Detection · Recommendation · Time-Series Forecast | Model Path/URI · Feature Columns · Prediction Column |\n| **Data Masking** | Hash SHA-256 · Tokenize · Nullify · Format-Preserving Encryption · Pseudonymize · Redact (→ ***) · Generalize | Columns to Mask |\n| **Schema Validate** | Strict Validation · Lenient Validation · Drift Detection · Schema Registry Check · Data Contract Validation | Schema Source (Inline/Confluent/AWS Glue/S3) |\n| **Dedup** | Exact Dedup · Key-based (Keep First/Last/Max) · Fuzzy Dedup · Streaming Dedup | Dedup Key Columns |\n\nFor Spark connectors (Python / Scala / Java), a **Spark Language** selector is also shown.\n\n#### 🔴 Sink — Dynamic configuration\n\nWhen you select a Sink connector, a **📤 Sink configuration** panel appears:\n\n| Connector | Available fields |\n|---|---|\n| Snowflake | Database · Schema · Table · Write Mode (append/overwrite/merge) |\n| BigQuery | Dataset · Table · Write Mode |\n| Redshift / PostgreSQL | Schema · Table · Write Mode (append/upsert/overwrite) |\n| ClickHouse | Table · Engine (MergeTree/ReplacingMergeTree/AggregatingMergeTree) · Write Mode |\n| Databricks Delta | Catalog · Schema · Table · Write Mode · Merge Keys · Z-Order By |\n| S3 | Bucket/Path · Format · Partition By |\n| Kafka Topic | Topic · Format (JSON/Avro/Protobuf) |\n| Redis | Key Pattern (e.g. `user:{id}`) · TTL (seconds) |\n| Elasticsearch | Index · ID Field |\n| Slack Alert | Channel · Message Template · Trigger Condition |\n| PagerDuty | Severity (critical/error/warning/info) · Filter Condition |\n\n---\n\n### Real-time structural validation\n\nThe canvas analyses the pipeline on every node addition and displays a banner:\n\n- **✅ Pipeline structure is valid** — at least one Source and one Sink are present\n- **⚠️ Pipeline has no Source node** — add a data source\n- **⚠️ Pipeline has no Sink node** — add a destination\n\n---\n\n### Node management\n\nEach node in the preview shows:\n- The **type icon** (🔵 Source / 🟢 Transform / 🔴 Sink)\n- The **node name**\n- The connector in brackets\n- An **⚙ operation** badge for transforms (e.g. `⚙ Mart Model`)\n- A **Spark Language** badge if applicable\n- A green **DQ ✓** badge if quality checks are enabled\n- An italic hint with the first filled configuration value\n- A **✕** button to delete the node individually without resetting the whole pipeline\n\n---\n\n### Execution modes\n\n**Batch**: Scheduled processing (cron), ideal for daily ETLs, reports, exports.\n\n**Streaming**: Real-time processing (< 1 second to a few minutes of latency), ideal for fraud detection, monitoring, recommendations.\n\n**Hybrid**: NEXUS automatically manages the batch → streaming transition based on volume and target latency. A cron schedule is required for the batch component.\n\n---\n\n### Built-in Data Quality\n\nEach Transform node can enable DQ checks via the **Data Quality checks** checkbox:\n\n```yaml\ntransform:\n name: tr_dbt_revenue\n dq_enabled: true\n dq_checks:\n - type: not_null\n columns: [user_id, event_type]\n - type: unique\n columns: [event_id]\n - type: row_count_gte\n value: 1000\n - type: custom_sql\n query: \"SELECT COUNT(*) FROM {{ table }} WHERE amount < 0\"\n expect: 0\n```\n\nIf a check fails, the pipeline is quarantined and an alert is sent.\n\n---\n\n### Enriched YAML / JSON export\n\nThe exported pipeline now contains the full `config:` block for each node, with all options filled in the UI. Full example:\n\n```yaml\npipeline:\n name: kafka-dbt-snowflake\n mode: batch\n schedule: 0 6 * * *\n version: '1.0'\n nodes:\n - id: src_01\n name: source_kafka_events\n type: Source\n connector: Kafka\n dq_enabled: false\n config:\n Topic: nexus.events\n Consumer Group: nexus-consumer\n Format: JSON\n Offset: latest\n\n - id: tr_01\n name: transform_dbt_revenue\n type: Transform\n connector: dbt SQL\n dq_enabled: true\n config:\n operation: Mart Model\n materialization: incremental\n dbt_target_profile: snowflake_prod\n threads: '8'\n\n - id: snk_01\n name: sink_snowflake_analytics\n type: Sink\n connector: Snowflake\n dq_enabled: false\n config:\n Database: ANALYTICS\n Schema: MARTS\n Table: REVENUE_BY_REGION\n Write Mode: overwrite\n```\n\nThe generated file is Git-versionable and deployable with:\n```bash\nnexus pipeline deploy --file kafka-dbt-snowflake.yaml --env prod\n```\n\"\"\",\n },\n \"spark\": {\n \"title\": \"4. Apache Spark Support\",\n \"content\": \"\"\"\n### Supported languages\n\nNEXUS generates native Spark code in **Python (PySpark)**, **Scala** and **Java**. The code generator adapts to the chosen template.\n\n### Available templates\n\n#### Basic ETL\nExtract → transform → load pipeline. Includes:\n- Reading from S3 (Parquet format)\n- Cleaning and deduplication\n- Data Quality via assertions\n- Partitioned write to destination\n\n#### Kafka Streaming\nKafka consumer pipeline with Spark Structured Streaming. Includes:\n- Reading from a Kafka topic with offset management\n- Time windowing (window / watermark)\n- Real-time aggregations\n- Writing to ClickHouse or any JDBC sink\n\n#### ML Pipeline\nSpark MLlib training and inference pipeline. Includes:\n- Feature engineering (VectorAssembler, StandardScaler)\n- Training with cross-validation\n- Best model selection\n- Model saving to S3\n\n#### Delta Lake\nDelta Lake table management pipeline. Includes:\n- Staging read\n- Smart MERGE (UPSERT)\n- OPTIMIZE + Z-ORDER for performance\n- VACUUM for retention management\n\n### Recommended Spark configuration\n\n| Workload | Executors | Memory/exec | Cores/exec |\n|---|---|---|---|\n| Standard ETL | 4–8 | 4g | 2 |\n| Streaming | 2–4 | 2g | 2 |\n| ML training | 8–16 | 8g | 4 |\n| Delta MERGE | 4–8 | 4g | 2 |\n\n### Spark execution modes\n\n**Local** (`local[*]`): For development and testing. No cluster required.\n\n**YARN**: For on-premise Hadoop clusters or EMR.\n\n**Kubernetes**: For cloud-native deployments. NEXUS generates the Helm chart.\n\n**Databricks**: Uses the Databricks Jobs API. NEXUS manages the cluster lifecycle.\n\"\"\",\n },\n \"connectors\": {\n \"title\": \"5. Connectors\",\n \"content\": \"\"\"\n### Connector architecture\n\nEach NEXUS connector is a Python plugin that implements the `NexusConnector` interface:\n\n```python\nfrom nexus.connectors import NexusConnector\n\nclass SnowflakeConnector(NexusConnector):\n def read(self, spark, config) -> DataFrame:\n return spark.read.format(\"snowflake\").options(**config).load()\n\n def write(self, df, config, mode=\"overwrite\"):\n df.write.format(\"snowflake\").options(**config).mode(mode).save()\n\n def test_connection(self, config) -> bool: ...\n```\n\n### Snowflake\n\n**Prerequisites**: Snowflake account, active warehouse, role with `USAGE` and `SELECT` permissions.\n\n**Recommended environment variables**:\n```bash\nNEXUS_SF_ACCOUNT=myorg-myaccount\nNEXUS_SF_USER=my_user\nNEXUS_SF_PASSWORD=**** # or private key\nNEXUS_SF_WAREHOUSE=COMPUTE_WH\nNEXUS_SF_DATABASE=NEXUS_DB\nNEXUS_SF_SCHEMA=PUBLIC\n```\n\n**Auth modes**: Password, Key Pair (RSA), OAuth 2.0, SSO (SAML).\n\n### Databricks — Subscription types & capabilities\n\nNEXUS supports **all Databricks subscription types**. Select your type in the\nConnectors → Databricks tab under \"Subscription type\". Fields adjust automatically.\n\n| Type | Unity Catalog | SQL Warehouse | Service Principal | Identity Provider | URL pattern | Notes |\n|---|:---:|:---:|:---:|---|---|---|\n| 🆓 Free / Community Edition | ⚠️ limited | ✅ (1 small) | ❌ | none | `community.cloud.databricks.com` | Personal use only, heavily restricted |\n| ☁️ AWS Standard | ❌ | ✅ | ❌ | AWS IAM / external SSO | `<workspace>.cloud.databricks.com` | No Unity Catalog, limited governance |\n| ☁️ AWS Premium / Enterprise | ✅ | ✅ | ✅ | AWS IAM / external SSO | `<workspace>.cloud.databricks.com` | Production ready, full governance |\n| 🔷 Azure Standard | ❌ | ✅ | ❌ | Azure AD | `adb-<id>.<region>.azuredatabricks.net` | Integrated with Azure AD |\n| 🔷 Azure Premium / Enterprise | ✅ | ✅ | ✅ | Azure AD | `adb-<id>.<region>.azuredatabricks.net` | Enterprise-grade security and governance |\n| 🟡 GCP Standard | ❌ | ✅ | ❌ | Google IAM / Identity | `<workspace>.gcp.databricks.com` | Limited governance features |\n| 🟡 GCP Premium / Enterprise | ✅ | ✅ | ✅ | Google IAM / Identity | `<workspace>.gcp.databricks.com` | Production ready |\n\n> ⚠️ **Azure Databricks Standard**: Unity Catalog not supported and no Service Principal.\n> Azure AD integration available. Data is in `hive_metastore`.\n> Upgrade to **Premium or Enterprise** for Unity Catalog.\n\n**Available authentication methods by type:**\n- **PAT (Personal Access Token)**: available on all types.\n- **Azure AAD (Bearer token)**: Azure only. Generate via `az account get-access-token`.\n- **Service Principal / OAuth M2M**: AWS Premium, Azure Premium, GCP Premium.\n\n**Up to 3 simultaneous Databricks connectors**: NEXUS lets you configure up to 3 independent\nDatabricks connectors (e.g. AWS Production, Azure Staging, Community Dev). In the Pipeline Canvas,\na selector appears when multiple connectors are configured.\n\n**Prerequisites**: Databricks workspace, All-Purpose or Job Cluster, Personal Access Token (or AAD/SP depending on type).\n\n**Unity Catalog**: NEXUS natively supports Unity Catalog for data governance and cross-workspace lineage. On types without Unity Catalog, the browser navigates `hive_metastore`.\n\n### Secrets management\n\nNEXUS never stores credentials in plain text. All connections go through the **NEXUS Vault**:\n\n```yaml\nnexus_secrets:\n snowflake_password:\n vault_path: secret/nexus/snowflake\n rotation: 90d\n databricks_token:\n vault_path: secret/nexus/databricks\n rotation: 30d\n```\n\n### Creating a custom connector\n\n```bash\nnexus connector new --name my-custom-connector\n# Generates the skeleton in ./connectors/my_custom_connector/\n```\n\"\"\",\n },\n \"copilot\": {\n \"title\": \"6. AI Co-pilot\",\n \"content\": \"\"\"\n### How it works\n\nThe NEXUS Co-pilot is an AI assistant specialized in data pipeline design. It understands:\n\n- The topology of your configured connectors\n- Your SLA and cost constraints\n- Common pipeline patterns (ETL, CDC, ML, alerting)\n- Spark and streaming best practices\n\n### Usage examples\n\n**Pipeline generation**\n```\nUser : \"Create a pipeline that reads orders from PostgreSQL,\n computes revenue by region with dbt, and loads to\n Snowflake every day at 6am.\"\n\nCopilot: ✅ Pipeline generated:\n - Source : PostgreSQL → orders table\n - Transform : dbt SQL → revenue_by_region model\n - Sink : Snowflake → ANALYTICS.REVENUE table\n - Schedule : 0 6 * * * (UTC)\n - Estimated SLA : ~45 min\n```\n\n**Optimization**\n```\nUser : \"My Spark job takes 3 hours, how do I optimize it?\"\n\nCopilot: Analyzing your configuration...\n 1. Enable spark.sql.adaptive.enabled=true\n 2. Reduce spark.default.parallelism to 200\n 3. Add .repartition(\"event_date\") before writing\n 4. Enable Snappy compression: parquet.compression=SNAPPY\n → Estimated gain: -60% on execution time\n```\n\n### Supported LLM models\n\n| Model | Use | Latency |\n|---|---|---|\n| GPT-4o | Complex generation | ~3s |\n| Claude 3.5 Sonnet | Generation + optimization | ~2s |\n| Llama 3.1 (local) | Air-gapped / sensitive data | ~8s |\n| Mistral Large | Standard generation | ~2s |\n\n### Configuration\n\n```yaml\n# nexus.yaml\ncopilot:\n provider: anthropic\n model: claude-3-5-sonnet\n max_tokens: 4096\n context_window: pipelines + connectors + metrics\n data_privacy: true # anonymizes names before sending to LLM\n```\n\"\"\",\n },\n \"deployment\": {\n \"title\": \"7. Deployment\",\n \"content\": \"\"\"\n### Streamlit Cloud (recommended for getting started)\n\n```bash\n# 1. Fork the NEXUS repo on GitHub\n# 2. Go to share.streamlit.io\n# 3. Connect your repo\n# 4. Configure secrets in Settings → Secrets:\n\n[secrets]\nOPENAI_API_KEY = \"sk-...\"\nSNOWFLAKE_PASSWORD = \"****\"\nDATABRICKS_TOKEN = \"dapi...\"\n```\n\n### Docker Compose (development)\n\n```yaml\n# docker-compose.yaml\nservices:\n nexus-ui:\n image: nexusdata/platform:latest\n ports: [\"8501:8501\"]\n environment:\n - NEXUS_SECRET_KEY=${SECRET_KEY}\n volumes:\n - ./pipelines:/app/pipelines\n\n nexus-scheduler:\n image: nexusdata/scheduler:latest\n depends_on: [postgres, redis]\n\n postgres:\n image: postgres:15-alpine\n environment:\n POSTGRES_DB: nexus_meta\n\n redis:\n image: redis:7-alpine\n```\n\n### Kubernetes (production)\n\n```bash\nhelm repo add nexus https://charts.nexusdata.io\nhelm install nexus nexus/nexus-platform \\\\\n --namespace nexus \\\\\n --set global.cloud=gcp \\\\\n --set spark.mode=kubernetes \\\\\n --set vault.enabled=true\n```\n\n### Key environment variables\n\n| Variable | Description | Required |\n|---|---|---|\n| `NEXUS_SECRET_KEY` | Internal encryption key | ✅ |\n| `NEXUS_VAULT_ADDR` | HashiCorp Vault URL | Production |\n| `NEXUS_DB_URL` | PostgreSQL for metadata | ✅ |\n| `NEXUS_REDIS_URL` | Redis for cache | ✅ |\n| `NEXUS_LOG_LEVEL` | DEBUG / INFO / WARN | No |\n\"\"\",\n },\n \"best_practices\": {\n \"title\": \"8. Best practices\",\n \"content\": \"\"\"\n### Pipeline design\n\n**✅ Do**\n- One pipeline = one single responsibility (SRP principle)\n- Use descriptive node names: `src_postgres_orders`, `tr_dbt_revenue`, `snk_snowflake_analytics`\n- Version all YAML pipelines in Git\n- Define an SLA per pipeline and configure corresponding alerts\n- Enable Data Quality on each Transform\n- Use Data Contracts between producers and consumers\n\n**❌ Don't**\n- Create \"catch-all\" pipelines that do everything (extraction + ML + reporting)\n- Hardcode secrets in YAML configuration\n- Ignore Spark OOM errors without investigating skew\n- Disable DQ checks in production\n\n### Spark\n\n```python\n# ✅ Best practice: adaptive query execution\nspark.conf.set(\"spark.sql.adaptive.enabled\", \"true\")\nspark.conf.set(\"spark.sql.adaptive.coalescePartitions.enabled\", \"true\")\n\n# ✅ Best practice: partition before writing\ndf.repartition(col(\"event_date\")).write.partitionBy(\"event_date\").parquet(...)\n\n# ✅ Best practice: cache reused DataFrames\ndf_clean.cache()\ndf_clean.count() # force the cache\n\n# ❌ Bad practice: collect() on a large DataFrame\nall_rows = df.collect() # guaranteed OOM on large datasets\n```\n\n### Streaming\n\n- Always define a **watermark** for late arrivals\n- Configure **checkpointing** on durable storage (S3, HDFS)\n- Monitor **Kafka lag** (target: < 10,000 messages)\n- Use `processingTime` trigger rather than `once` in production\n\n### Security\n\n- Enable **NEXUS RBAC**: each team only sees their own pipelines\n- Use dedicated **Service Accounts** per pipeline (least privilege principle)\n- Audit access to sensitive data via the NEXUS log\n- Apply automatic **Data Masking** on PII columns\n\n### Cloud cost\n\n| Lever | Potential savings |\n|---|---|\n| Spot Instances for batch Spark jobs | 60–80% |\n| Databricks autoscaling (min/max workers) | 40–60% |\n| Parquet compression + Z-ORDER ClickHouse | 30–50% I/O |\n| Well-configured partition pruning | 20–40% scan |\n\"\"\",\n },\n },\n}\n\nSECTION_KEYS = [\"intro\", \"quickstart\", \"canvas\", \"spark\", \"connectors\", \"copilot\", \"deployment\", \"best_practices\"]\n\n\ndef render_manual(T, lang_key):\n st.markdown(f\"### {T['manual_title']}\")\n st.caption(T[\"manual_subtitle\"])\n st.divider()\n\n content_lang = MANUAL_CONTENT.get(lang_key, MANUAL_CONTENT[\"fr\"])\n search = st.text_input(f\"🔍 {T['manual_search']}\", placeholder=\"spark, kafka, snowflake, lineage...\")\n\n section_labels = [content_lang[k][\"title\"] for k in SECTION_KEYS]\n toc_labels = [T[f\"manual_s{i+1}\"] for i in range(8)]\n\n col_toc, col_content = st.columns([1, 3])\n\n with col_toc:\n st.markdown(f\"**{T['manual_toc']}**\")\n if \"manual_section\" not in st.session_state:\n st.session_state[\"manual_section\"] = 0\n for i, lbl in enumerate(toc_labels):\n btn_type = \"primary\" if st.session_state[\"manual_section\"] == i else \"secondary\"\n if st.button(lbl, key=f\"toc_{i}\", use_container_width=True, type=btn_type):\n st.session_state[\"manual_section\"] = i\n\n with col_content:\n idx = st.session_state.get(\"manual_section\", 0)\n key = SECTION_KEYS[idx]\n section = content_lang[key]\n\n if search:\n # Filter content\n matched = []\n for k in SECTION_KEYS:\n sec = content_lang[k]\n if search.lower() in sec[\"content\"].lower() or search.lower() in sec[\"title\"].lower():\n matched.append(sec)\n if matched:\n st.success(f\"🔍 {len(matched)} section(s) trouvée(s) / found\")\n for sec in matched:\n st.markdown(f\"#### {sec['title']}\")\n st.markdown(sec[\"content\"])\n st.divider()\n else:\n st.warning(f\"Aucun résultat pour '{search}' / No results for '{search}'\")\n else:\n st.markdown(f\"#### {section['title']}\")\n st.markdown(section[\"content\"])\n"}}}} |