Architektura
Usługi AI
Platforma DataFlow AI dostarcza dwie usługi Python 3.12 / FastAPI, które wnoszą możliwości dużych modeli językowych do zasobu danych: Copilot do konwersacyjnej i generatywnej asysty oraz Migration Engine do konwersji starszych ETL na potoki DataFlow.
Przegląd
Obie usługi AI znajdują się pod backend/ai-services/, są budowane za pomocą Poetry i działają na FastAPI. Współdzielą instancję PostgreSQL platformy (Copilot używa również jej rozszerzenia pgvector dla RAG).
| Usługa | Ścieżka | Port | Przeznaczenie |
|---|---|---|---|
| Copilot | backend/ai-services/copilot/ | 8090 | NL-to-pipeline, konwersacyjna AI, NL-to-SQL, wyszukiwanie RAG, sugestie, diagnostyka błędów, agentowy builder, RCA |
| Migration Engine | backend/ai-services/migration-engine/ | 8091 | Konwertuje starsze ETL (Informatica PowerCenter, Alteryx, SSIS, DataStage) na potoki YAML DataFlow |
Definiującą właściwością obu usług jest płynna degradacja — awarie RAG, katalogu i LLM wracają do czatu bez RAG, gotowych schematów lub jawnych znaczników llm_unavailable, zamiast ujawniać fałszywki. Drugą jest wszechobecne ocenianie pewności — każdy wynik AI niesie ze sobą ocenę pewności w zakresie 0–1, a Migration Engine używa jej jako twardej bramki wydania.
Usługa Copilot
Struktura aplikacji
copilot/copilot/main.py buduje aplikację FastAPI DataFlow AI Copilot v0.3.0.
- Potrójne montowanie tras — ten sam zestaw routerów jest montowany pod trzema prefiksami, aby był osiągalny niezależnie od tego, jak adresuje go brama lub frontend:
/api/v1/ai/**— kanoniczne montowanie (api/router.py)./api/v1/copilot/**—baseURL=/api/v1frontendu plus/copilot/chat./api/copilot/**— dostęp bezpośredni, gdyVITE_API_URL=/api.
- Cykl życia — przy starcie usługa inicjalizuje pulę pgvector
RAGServicei zapewnia schemat embeddingów, degradując płynnie dorag_mode: "unavailable", jeśli pgvector jest nieosiągalny; pula jest zamykana przy wyłączeniu. - Endpointy operacyjne —
/health,/ready(zwraca 503 z przyczynamipgvector_unavailable/llm_unavailable, gdy zdegradowane) oraz/metrics(minimalna ekspozycja tekstowa Prometheus: informacje o usłudze, czas działania, licznik żądań). - CORS udostępnia
X-Request-IdiX-Copilot-Confidence.
Konfiguracja
Konfiguracja używa pydantic-settings i jest sterowana zmiennymi środowiskowymi (copilot/config.py). Godne uwagi wartości domyślne:
| Ustawienie | Wartość domyślna |
|---|---|
anthropic_api_key | "" |
anthropic_model | claude-sonnet-4-20250514 |
database_url | postgresql+asyncpg://postgres:postgres@localhost:5432/copilot |
catalog_base_url | http://localhost:8585/api/v1 |
service_port | 8090 |
rag_similarity_threshold | 0.72 |
rag_max_results | 5 |
Zależności (pyproject.toml): fastapi, uvicorn, anthropic ^0.39, asyncpg, pgvector, httpx, pyyaml, numpy. sentence-transformers ^3.3 to opcjonalny dodatek (grupa ml) — gdy nie jest zainstalowany, wyszukiwanie wektorowe RAG ulega degradacji.
Fabryka dostawców LLM
Podłączalna warstwa dostawców znajduje się pod copilot/providers/ (base.py, factory.py, trzy implementacje). ABC LLMProvider definiuje complete() i stream(), zwracając znormalizowane CompletionResponse (treść, model, tokeny prompt/completion, latency_ms, finish_reason) oraz delty StreamChunk. LLMProviderError to jednolity typ błędu.
| Dostawca | Plik | Domyślny model | Uwagi |
|---|---|---|---|
| anthropic | anthropic_provider.py | claude-sonnet-4-6-20251001 | Oficjalny SDK anthropic; natywny argument system; prawdziwe strumieniowanie |
| openrouter | openrouter_provider.py | openai/gpt-oss-120b:free | Surowy httpx do API OpenRouter zgodnego z OpenAI; wysyła HTTP-Referer / X-Title |
| local | local_provider.py | llama3.2 | Dowolny samodzielnie hostowany endpoint zgodny z OpenAI — Ollama, vLLM, LM Studio, llama.cpp |
factory.py odczytuje zmienną środowiskową LLM_PROVIDER (anthropic | openrouter | local; domyślnie anthropic), buforuje bezpieczny wątkowo singleton i oferuje reset_provider() do przeładowania. Starszy shim ClaudeClient (clients/claude_client.py) jest utrzymywany dla wstecznej kompatybilności — każda usługa Copilota wywołuje self._claude.generate/stream/complete, ale shim teraz kieruje przez factory.get_provider(). Przełączenie LLM_PROVIDER przerabia więc cały stos Copilota bez zmian po stronie wywołujących. CatalogClient (clients/catalog_client.py) to asynchroniczny klient httpx do katalogu zgodnego z OpenMetadata (search_tables(), get_table(), get_lineage()).
Dwie odrębne ścieżki dostępu do LLM
Główne usługi Copilota kierują wywołania LLM przez podłączalną fabrykę LLMProvider za pośrednictwem shima ClaudeClient. Jednak AgentService Copilota oraz LLMConverter Migration Engine wywołują SDK anthropic bezpośrednio — nie są na ścieżce podłączalnej fabryki.
Endpointy API
Wszystkie endpointy są osiągalne pod każdym z /api/v1/ai, /api/v1/copilot oraz /api/copilot.
| Endpoint | Metoda | Przeznaczenie |
|---|---|---|
/chat | POST | Konwersacyjny copilot (wzbogacony RAG), zwraca ChatResponse |
/chat/stream | GET | Strumieniowy czat SSE — zdarzenia token / done / error |
/suggest | POST | Inline'owe uzupełnienia kodu (yaml/sql/python) |
/insights | GET | Proaktywne rekomendacje (buforowane 300s) |
/generate-pipeline | POST | NL → potok YAML DataFlow |
/sql/generate | POST | NL → SQL |
/sql/explain | POST | Wyjaśnienie SQL w prostym języku |
/sql/optimize | POST | Sugestie optymalizacji SQL |
/sql/validate | POST | Sprawdzenie poprawności SQL względem znanego schematu |
/semantic/query | POST | NL→SQL ze wzbogaceniem glosariuszem biznesowym |
/semantic/glossary | GET | Lista metryk/wymiarów/filtrów glosariusza |
/diagnose | POST | Strukturalna diagnostyka błędów |
/quality/generate-rules | POST | NL → reguły jakości danych |
/agent/chat | POST | Agentowy builder potoków (pętla tool_use) |
/agent/approve | POST | Zatwierdzenie oczekującej destrukcyjnej akcji agenta |
/agent/status/{id} | GET | Stan sesji agenta |
/schema/match | POST | Dopasowanie kolumn źródło→cel przez LLM |
/schema/match/override | POST | Zastosowanie ręcznych nadpisań dopasowania |
/schema/match/{id} | GET | Pobranie zapisanego wyniku dopasowania |
/describe/asset | POST | Automatyczne generowanie opisów zasobów katalogu |
/catalog/ask | POST | Pytania i odpowiedzi katalogu ugruntowane w metadata-service |
/rca/analyze | POST | Agent analizy przyczyn źródłowych |
/provider/status | GET | Kondycja/model aktywnego dostawcy LLM |
CopilotService — centralny orkiestrator
services/copilot_service.py to centralny orkiestrator. Jego przepływ chat() to:
- Routing intencji — wykrywanie słów kluczowych (
_SQL_INTENT_KEYWORDS,_ERROR_INTENT_INDICATORS) kieruje pytania SQL do NL-to-SQL, a zgłoszenia błędów do diagnostyki błędów. - Wzbogacenie RAG —
RAGService.get_context_for_query()działa w trybie best-effort, wracając do czatu bez RAG przy awarii. - Buduje wzbogacony prompt systemowy (
build_chat_system_prompt) wstrzykujący kontekst potoku plus wyniki RAG. - Wywołuje Claude poprzez
ClaudeClient.generate(). _parse_response()wyodrębnia bloki[ACTION type=... label=... payload={...}]do strukturalnych obiektówAction.- Stosuje heurystykę pewności — baza 0,7, +0,15 za RAG, +0,05 za kontekst potoku.
chat_stream() produkuje tokeny poprzez strumieniowanie dostawcy. get_insights() używa wewnątrzprocesowego bufora TTL (300s) kluczowanego na (pipeline_id, limit) — wywołanie LLM jest wolne (~50s), a pulpit odpytuje co 60s, ze statycznym _fallback_insights() przy awarii LLM. Dialekt SQL jest automatycznie wykrywany z tekstu komunikatu (Teradata / Snowflake / Postgres / SAP HANA / MSSQL).
NL-to-SQL
services/nl_to_sql.py dostarcza NLToSQLService — generowanie, wyjaśnianie, optymalizację i walidację SQL w pięciu dialektach (enum SQLDialect: snowflake, teradata, postgresql, sap_hana, mssql). Posiada bogate per-dialektowe bloki podpowiedzi (_DIALECT_HINTS) oraz cztery prompty systemowe. Przepływ pracy:
- Zbuduj kontekst schematu z RAG
search_with_scores()(encje tabel/kolumn). - Opcjonalnie zastosuj wzbogacenie warstwą semantyczną (domyślnie włączone).
- Sformatuj per-dialektowy prompt systemowy i wywołaj Claude (temperatura 0,1).
- Wyodrębnij SQL z bloku w ogrodzeniu;
_extract_table_references()poprzez regex; heurystyka_estimate_confidence();_detect_warnings()oznaczaSELECT *,DELETE/UPDATEbezWHERE,DROP/TRUNCATEoraz nieprawidłowe dla dialektuLIMIT.
Generowanie potoków
services/pipeline_generator.py — PipelineGenerator.generate() pobiera schemat katalogu dla żądanych source_systems, pobiera podobne szablony RAG w trybie best-effort, wywołuje Claude z _GENERATOR_SYSTEM_PROMPT (specyfikacja DSL YAML DataFlow), parsuje YAML, wyodrębnia PipelineNode / PipelineEdge dla grafu frontendu i stosuje heurystykę pewności względem strukturalnej jakości YAML.
RAG i magazyn wektorowy
services/rag_service.py oraz services/embedding_pipeline.py implementują RAG nad podobieństwem kosinusowym pgvector.
- Embeddingi używają sentence-transformers
all-MiniLM-L6-v2(EMBEDDING_DIM= 384), ładowanym leniwie. - Tabela
catalog_embeddingsprzechowujeentity_type,entity_id,entity_name,workspace_id,content,metadataJSONB oraz kolumnęvector(384), z indeksem kosinusowymivfflat(lists=100) plus indeksami btree workspace i entity_type. search()/search_with_scores()stosująrag_similarity_threshold(0,72) oraz opcjonalne filtryworkspace_id/entity_type, sortującBY embedding <=>.- Gdy pgvector jest niedostępny, usługa degraduje do pustych wyników (
mode="unavailable") — nie ma cichego powrotu do wyszukiwania słów kluczowych. - Operacje CRUD:
index_catalog()upsert,delete_by_entity/all/stale,get_stats.
EmbeddingPipeline indeksuje metadane katalogu do magazynu wektorowego. Dostarcza wbudowany korpus 6 fragmentów dokumentów (Pipeline YAML DSL Reference, Connector Configuration Guide, Polkomtel Data Landscape, ETL Best Practices, Common Error Patterns, SQL Dialect Reference) oraz 5 szablonów potoków. run_full_index() pobiera tabele i kolumny z 6 usług Polkomtela (teradata-dwh-mona, sap-hana, snowflake-analytics, databricks-lakehouse, oracle-legacy, mssql-departmental) z rozmiarem partii 64.
Zastrzeżenie dotyczące opcjonalnej zależności
Brakujący moduł sentence_transformers był udokumentowaną przyczyną błędów HTTP 500 w czacie. Dodatek ml musi być zainstalowany, aby pełne wyszukiwanie wektorowe RAG działało.
Agentowy builder
services/agent_service.py dostarcza AgentService — autonomiczny builder potoków używający Claude tool_use (agentowy poziom 4). Pętla działa do 15 iteracji. Sześć narzędzi jest zdefiniowanych w AGENT_TOOLS:
| Narzędzie | Destrukcyjne | Przeznaczenie |
|---|---|---|
list_connections | nie | Wyliczenie dostępnych połączeń |
discover_schema | nie | Odkrycie schematu źródłowego |
generate_pipeline | nie | Wyprodukowanie definicji potoku |
validate_pipeline | nie | Walidacja potoku |
create_pipeline | tak | Utrwalenie nowego potoku (wymaga zatwierdzenia) |
run_pipeline | tak | Wykonanie potoku (wymaga zatwierdzenia) |
_ToolBackend wykonuje operacje względem prawdziwych API platformy i katalogu, z fallbackami opartymi na wiedzy domenowej (np. gotowe schematy CDR/billing Polkomtela, gdy katalog jest niedostępny). Stan per-sesja jest przechowywany w słowniku AgentSession w pamięci. Bramka zatwierdzeń wstrzymuje destrukcyjne narzędzia jako PendingAction; approve() wznawia konwersację. Agent może kierować żądania w formacie Anthropic przez /v1/messages OpenRouter, gdy skonfigurowany jest tylko OPENROUTER_API_KEY.
Agent RCA
services/rca_agent.py (FIX-052) dostarcza RcaAgent.analyze() do analizy przyczyn źródłowych incydentów. Wykonuje 4 prawdziwe wywołania narzędzi HTTP — ostatnie alerty i uruchomienia (monitor-service), logi uruchomień oraz oś czasu zmian schematu (metadata-service) — a następnie syntetyzuje poprzez skonfigurowany LLMProvider (temperatura 0,2) w strukturalne RcaResponse: podsumowanie, oś czasu, 2–4 uszeregowane wpisy Hypothesis (każdy z pewnością, dowodami i suggestedAction) oraz citedAssets. Niesie prawdziwe model, tokenCount, latencyMs oraz toolCallCount, używa tolerancyjnego parsowania JSON i nigdy nie wymyśla treści.
Pozostałe usługi Copilota
- Dopasowywacz schematów (
services/schema_matcher.py) —SchemaMatcherService.match_schemas()wykonuje dopasowanie kolumn przez LLM dla migracji. Z opcjonalnym wzbogaceniem RAG wywołuje Claude (temperatura 0,2) i parsuje JSON doSchemaMatchResultwpisówColumnMatchsklasyfikowanych jakoEXACT/SEMANTIC/TYPE_COERCE/TRANSFORM_NEEDED, każdy z pewnością,transform_expressioni uzasadnieniem. Wyniki są przechowywane w pamięci w_match_store;apply_overrides()obsługuje akcje użytkownika accept/reject/modify. Prompt domeny polskiej telekomunikacji obsługuje polskie nazwy kolumn. - Generator reguł jakości (
services/quality_rule_generator.py) —QualityRuleGenerator.generate_rules()zamienia NL na strukturalne reguły w 10 typachRuleType(NOT_NULL, UNIQUE, RANGE, REGEX, ROW_COUNT, CUSTOM_SQL, FRESHNESS, COMPLETENESS, SCHEMA_MATCH, STATISTICAL). Post-walidacja obniża pewność dla kolumn nieobecnych w kontekście schematu. Jego prompt osadza kontekst Polkomtela (PESEL^\d{11}$, MSISDN^48\d{9}$, CDR, przychód-nigdy-ujemny). - Warstwa semantyczna (
services/semantic_layer.py) —SemanticLayerServiceto warstwa wzbogacania glosariuszem biznesowym przed NL-to-SQL. Jego wbudowany glosariusz Polkomtela zawiera ~11 metryk (wskaźnik churn, ARPU, MoU, zużycie danych, net adds, przychód), ~14 wymiarów i 7 szablonów filtrów.resolve_terms()skanuje pytanie (najdłuższe dopasowanie),enrich_prompt()wstrzykuje formuły i mapowania, a następnie deleguje doNLToSQLService.generate_sql().
Strategia promptów
Katalog copilot/prompts/ koduje wiedzę domenową platformy:
chat_prompt.py— dużyCHAT_SYSTEM_PROMPTkodujący pełny krajobraz danych Polkomtela (DWH-MONA Teradata, SAP HANA, Snowflake, Databricks, Oracle, MSSQL, Kafka, S3), glosariusz telekomunikacyjny (CDR, MSISDN, IMSI, ARPU, churn), DSL YAML potoków, konektory, najlepsze praktyki ETL oraz format bloku ACTION.suggest_prompt.py— prompty uzupełnień specyficzne dla języka (konfiguracja YAML/SQL/połączenia) z formatem wyjściaconfidence|text.insights_prompt.py— 6 kategorii wglądu, wyjście jako tablica JSON.error_diagnosis_prompt.py— 8 kategorii błędów ze specyficzną dla Polkomtela wiedzą o błędach (Teradata TPT/PERM, SAP HANA CDC), wyjście jako obiekt JSON.schema_match_prompt.py— 4 poziomy reguł dopasowania z pasmami pewności.
Modele danych Copilota
Modele Pydantic pod copilot/models/ obejmują chat.py (Role, Message, PipelineContext, ChatRequest, Action/ActionType, ChatResponse), suggestion.py, insight.py, pipeline.py, sql.py (SQLDialect, SQLRequest/Result/ValidationResult, modele diagnostyki błędów), quality_rule.py, schema_match.py, semantic.py oraz rca.py (RcaRequest/Response, TimelineEvent, Hypothesis, CitedAsset). Wszystkie niosą wartość zmiennoprzecinkową confidence, gdzie ma to zastosowanie.
Migration Engine
Struktura aplikacji
Migration Engine to aplikacja FastAPI DataFlow Migration Engine v0.2.0 na porcie 8091, montowana pod /api/v1/migration oraz /api/migration. Konwertuje starsze skrypty ETL na YAML DataFlow, używając dopasowywania wzorców opartego na regułach plus tłumaczenia wspomaganego LLM. Konfiguracja: anthropic_api_key, anthropic_model = claude-sonnet-4-20250514, max_upload_size_mb = 50, upload_dir = /tmp/migration-uploads.
Co migruje
Enum MigrationType obejmuje cztery starsze narzędzia ETL (nie dialekty SQL):
| Narzędzie | Rozszerzenie | Parser |
|---|---|---|
| Informatica PowerCenter | .xml | powercenter_parser.py |
| Alteryx | .yxmd | alteryx_parser.py |
| SSIS | .dtsx | ssis_parser.py |
| DataStage | .dsx | datastage_parser.py |
Przesyłanie obecnie akceptuje tylko .xml, .yxmd i .dtsx; parser DataStage istnieje i jest podpięty do silnika reguł, ale .dsx nie znajduje się w _ALLOWED_EXTENSIONS.
Endpointy API
| Endpoint | Metoda | Przeznaczenie |
|---|---|---|
/upload | POST | Przesyłanie multipart — uruchamia pełny potok w trybie inline |
/jobs | GET | Stronicowana/filtrowana/sortowana lista zadań |
/jobs/{id}/status | GET | Status zadania (alias starszy /{id}/status) |
/jobs/{id}/report | GET | Pełny MigrationReport ze statystykami |
/jobs/{id}/download | GET | Pobranie skonwertowanego YAML (lub JSON) |
/jobs/{id}/validate | POST | Uruchomienie zestawu 6 sprawdzeń walidacji |
/jobs/{id}/convert | POST | Ponowne wyzwolenie konwersji |
Potok parsuj → konwertuj → waliduj
Cykl życia MigrationStatus to: uploaded → parsing → parsed → converting → validating → validated → completed | completed_with_warnings | failed. Endpoint /upload uruchamia wszystkie etapy w trybie inline.
upload file (.xml / .yxmd / .dtsx)
│
▼
┌───────────────────┐ Stage 1 — PARSE
│ parsers/<tool> │ tool-specific parser → common WorkflowAST
└─────────┬─────────┘ (WorkflowAST → MappingAST → SourceDefinition /
│ Transformation / TransformationField / Connector)
▼
┌───────────────────┐ Stage 2 — CONVERT
│ RuleEngine.convert│ TRANSFORM_RULES registry handles known types
│ + Expression │ deterministically; ExpressionTranslator turns
│ Translator │ PowerCenter expression language into SQL
│ → LLMConverter │ sub-threshold / unknown types fall back to LLM
│ → YamlGenerator │ assembles the final DataFlow YAML
└─────────┬─────────┘
▼
┌───────────────────┐ Stage 3 — VALIDATE
│ PipelineValidator │ 6 checks on the generated YAML
└─────────┬─────────┘
▼
release gate: completed only if confidence ≥ 0.85
Etap 1 — Parsowanie. Parser dla każdego narzędzia źródłowego zamienia plik we wspólny WorkflowAST. powercenter_parser.py i alteryx_parser.py używają lxml; ssis_parser.py odczytuje XML DTS:Executable (zadania Data Flow / Control Flow, Connection Managers, Variables, osadzony SQL); datastage_parser.py odczytuje zastrzeżony format tekstowy (bloki BEGIN DSJOB … END DSJOB). Wszystkie udostępniają metodę klasową get_confidence(type) i rozszerzają bazowy parsers/base.py.
Etap 2 — Konwersja. converters/rule_engine.py — RuleEngine.convert() przechodzi przez każdą transformację. Rejestr TRANSFORM_RULES podklas TransformRule deterministycznie obsługuje 13 typów PowerCenter:
| Typ źródłowy | Cel DataFlow | Pewność |
|---|---|---|
| Source Qualifier | source_connector_sql_pushdown | 0,90–0,95 |
| Expression | sql_expression | 0,85 |
| Lookup Procedure | sql_join_pushdown | 0,65–0,85 |
| Aggregator | sql_group_by | 0,95 |
| Filter | sql_where | 0,98 |
| Joiner | sql_join | 0,90 |
| Sorter | sql_order_by | 0,98 |
| Router | conditional_branch (CASE WHEN) | 0,85 |
| Sequence Generator | sequence_generator (ROW_NUMBER) | 0,90 |
| Update Strategy | upsert_strategy | 0,80 |
| Union | sql_union_all | 0,95 |
| Rank | sql_rank (okno RANK()) | 0,85 |
| Normalizer | normalizer (unpivot) | 0,70 |
Etapy Alteryx (Filter/Formula/Summarize/Join/Sort/Union/AlteryxSelect) i DataStage (PxFilter/PxAggregator/PxJoin/PxLookup/PxSort/PxMerge/PxChangeCapture/PxSCD/CTransformerStage/PxModify/ContainerView) mają własne wbudowane bloki konwersji. _LLM_FALLBACK_THRESHOLD = 0,60 — typy bez reguły lub z pewnością poniżej progu spadają do konwertera LLM.
ExpressionTranslator (converters/expression_translator.py) tłumaczy język wyrażeń PowerCenter na SQL. Rekurencyjnie zstępujący tokenizer/parser mapuje ~60 funkcji poprzez PC_TO_SQL_FUNCTIONS, ze specjalizowanymi handlerami (_fn_iif → CASE WHEN, _fn_decode → CASE, NVL → COALESCE, SUBSTR → SUBSTRING, ADD_TO_DATE → INTERVAL, mapowanie tokenów formatu daty). Obsługuje zmienne $$parameter; nieznane funkcje przechodzą dalej z ostrzeżeniem i spadkiem pewności.
LLMConverter (converters/llm_converter.py) to fallback Claude dla złożonych transformacji. Używa SDK anthropic bezpośrednio (anthropic.AsyncAnthropic) — nie fabryki dostawców Copilota. Trzy specjalizowane prompty systemowe obejmują przypadek ogólny, procedury składowane oraz logikę transformacji niestandardowej/Java. Przy błędzie uwierzytelnienia API, limitu szybkości lub innym zwraca _unavailable_result() z conversion_source="llm_unavailable", pewnością 0,0 oraz requires_manual_review=True — odróżniając autentyczny wynik LLM od fallbacku awarii. Enum ConversionSource to rule_engine | llm | llm_unavailable | unsupported.
YamlGenerator (converters/yaml_generator.py) składa końcowy YAML DataFlow — klasyfikuje węzły na źródła/transformacje/cele, buduje powiązanie depends_on z krawędzi, wstrzykuje 3 domyślne sprawdzenia jakości (row_count, null_percentage, duplicate) plus per-ujściowe sprawdzenia walidacji schematu i sprawdzenie low_confidence_reconciliation dla mapowań poniżej 0,80 oraz dodaje metadane (generated_at, overall_confidence, warnings_count).
Etap 3 — Walidacja. validators/pipeline_validator.py — PipelineValidator.validate() uruchamia 6 sprawdzeń wygenerowanego YAML: składnia YAML, wymagane klucze potoku (name, nodes), schemat węzła (id/type, prawidłowe typy, prawidłowe konektory), odwołania krawędzi rozwiązujące się do id węzłów oraz skan niebezpiecznego SQL (DROP TABLE/DATABASE, TRUNCATE, ALTER TABLE, EXEC, xp_cmdshell). Zwraca ValidationResult z flagą is_valid plus problemami z prefiksem ERROR/WARNING.
Bramkowanie pewności
Bramka wydania (api/upload.py::collect_blocking_conversion_issues) oznacza zadanie jako completed tylko wtedy, gdy spełnione są wszystkie poniższe warunki:
- Ogólna pewność ≥ 0,85.
- Brak obiektów poniżej pewności 0,80.
- Brak obiektów wymagających ręcznego przeglądu.
- Brak problemów walidacji.
W przeciwnym razie zadanie jest oznaczane jako failed.
Usługi i trwałość
services/migration_service.py—MigrationServiceopakowuje magazyn zadań.list_jobs()filtruje/sortuje/stronicuje;validate_output()uruchamia bogatszy zestaw 6 sprawdzeń (składnia YAML, bezpieczeństwo SQL, pokrycie transformacji ≥ 50%, pewność ≥ 60%, kompletność węzłów dla źródła+ujścia, problemy z mapowaniem);start_conversion()obsługuje endpoint ponownej konwersji.services/report_generator.py— produkuje wskaźnikiMappingSummaryiEffortEstimateprzy użyciu modelu osobogodzin: 0,25h bazowo na mapowanie, 2,0h na ręczny przegląd, 1,0h na konwersję wspomaganą LLM, 0,5h testowania, 4,0h integracji; progi pewności 0,85 / 0,60 / 0,40.
Trwałość zadań to słownik _jobs w pamięci, który jest również utrwalany do jobs-store.json w katalogu przesyłania (persist_job() / save_jobs_store() / _load_jobs_store()) — przetrwa restarty dzięki plikowi JSON. Nie ma prawdziwej bazy danych.
Modele danych migracji
migration/models/migration.py definiuje MigrationType, MigrationStatus, MigrationJob, UploadResponse, MigrationReport (total_objects / auto_converted / needs_review / manual_required), PaginatedJobsResponse, ValidationCheckResult, ValidationResponse oraz ConvertResponse. migration/models/mapping.py definiuje ConversionSource, ObjectMapping, ConversionResult oraz dataclasy AST SourceDefinition, TransformationField, Transformation, Connector, MappingAST i WorkflowAST.
Kluczowe obserwacje
- Dwie odrębne ścieżki dostępu do LLM — Copilot używa podłączalnej fabryki
LLMProvider(anthropic/openrouter/local) kierowanej przez shimClaudeClient, podczas gdyLLMConverterMigration Engine orazAgentServiceCopilota wywołują SDKanthropicbezpośrednio. - Embeddingi używają
all-MiniLM-L6-v2(384-wymiarowe) z indeksem kosinusowymivfflatpgvector — opcjonalna zależność, której brak powodował błędy 500 w czacie. - Płynna degradacja wszędzie — awarie RAG, katalogu i LLM wracają do czatu bez RAG, gotowych schematów lub znaczników
llm_unavailable; endpoint/readyCopilota uczciwie raportujedegraded. - Pewność jest wszechobecna — każdy wynik AI (czat, SQL, reguły, dopasowania, konwersje, hipotezy RCA) niesie ocenę pewności w zakresie 0–1; Migration Engine używa jej jako twardej bramki wydania przy ≥ 0,85.
- Silne zakodowanie domeny Polkomtel/telekomunikacja — krajobraz danych, glosariusz CDR/MSISDN/ARPU, regexy PESEL/MSISDN oraz obsługa polskojęzycznych nazw kolumn są wbudowane w prompty i glosariusz semantyczny.