from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]
def read(p): return (ROOT/p).read_text(encoding='utf-8')
def test_v015_router_and_ui():
    main=read('app/main.py'); api=read('app/api/v015.py')
    assert 'v015_router' in main  and '/semantic-hub' in main
    for route in ['/summary','/glossary','/semantic/models','/semantic/query','/search','/knowledge-graph','/impact/{node_id}']: assert route in api
    for f in ['semantic-hub.html','business-glossary.html','enterprise-search.html']: assert (ROOT/'app/static'/f).exists()
def test_v015_models_and_migration():
    entities=read('app/models/entities.py'); migration=read('migrations/015_enterprise_data_fabric.sql')
    for name in ['BusinessTerm','SemanticModel','SemanticMetric','SemanticDimension','KnowledgeGraphNode','KnowledgeGraphEdge','SemanticPermission','SemanticQueryAudit']: assert f'class {name}' in entities
    for table in ['business_terms_v015','semantic_models_v015','semantic_metrics_v015','semantic_dimensions_v015','knowledge_graph_nodes_v015','knowledge_graph_edges_v015','semantic_permissions_v015','semantic_query_audit_v015']: assert table in migration
def test_v015_governance_and_query_engine():
    service=read('app/services/semantic_engine.py'); api=read('app/api/v015.py')
    assert 'can_read_model' in service and 'semantic_plan' in service and 'audit_query' in service
    assert 'row_filter' in api and 'masking' in api and 'execution_note' in api
def test_v015_docs():
    for f in ['USER_GUIDE_V015.md','ADMIN_GUIDE_V015.md','HOMOLOGATION_V015.md']: assert (ROOT/f).exists()
