# Core Components Distinction Guide This document aims to clarify the distinction between the different "Core" components within the **SecInterp** project to avoid confusion for both human developers and AI agents. ## ⚠️ The Fundamental Distinction Two "Core" entities coexist in this development environment: 1. **SecInterp Core** (The Project's Kernel): * **Location**: `/core` directory within the project root. * **Purpose**: Contains pure business logic, geological algorithms, processing services, and domain models (DTOs) specific to SecInterp. * **Current State**: **Decoupled**. As of version 2.8.0, this module has been sanitized to have no direct dependencies on QGIS live classes during heavy processing (Thread-Safe). 2. **QGIS Core** (The QGIS API): * **Reference**: `qgis.core` Python package. * **Purpose**: Provides the underlying geospatial infrastructure (geometries, layers, projects, CRS). * **Interaction**: SecInterp uses `qgis.core` to extract data in the main thread, but the **SecInterp Core** processes this data using agnostic types (WKT, dictionaries, primitives). --- ## 🧭 Guidelines for Developers and AI To maintain architectural integrity, follow these directives: ### 1. Do not assume "Core" always means QGIS If asked to "review the core", it almost exclusively refers to the `/core` directory of this plugin. Do not attempt to search for or modify internal files of the QGIS engine. ### 2. Data Boundaries (Decoupling) * **Inside `/core`**: Agnostic domain types must be used. Avoid instantiating `QgsVectorLayer` or accessing `QgsProject.instance()` within kernel services. Use `DomainGeometry` (WKT) and attribute dictionaries. * **Inside `/gui`**: This is where the translation between the real QGIS API (`qgis.core`) and the **SecInterp Core** takes place. Geometries are extracted and DTOs are prepared here. ### 3. File Naming and Imports * **Local Files**: Files in `core/` (e.g., `core/services/geology_service.py`) are the **SecInterp Brain**. * **External API**: Imports starting with `qgis.core`, `qgis.gui`, or `qgis.utils` are **External Dependencies**. * **Naming Rule**: In discussions or code comments, use "Internal Core" to refer to `/core` and "PyQGIS API" for the software's API. ### 4. The "Extract-then-Compute" Pattern To avoid future complications, the data flow **MUST** follow this pattern: 1. **GUI/Task Interface Layer**: Receives QGIS objects (`QgsVectorLayer`, `QgsFeature`). Extracts what is necessary (WKT geometry, attribute dictionaries). 2. **Core Layer**: Receives only the extracted data (strings, dicts, floats). Performs heavy geometric calculations. 3. **Result**: The Core returns DTOs (Data Transfer Objects) defined in `core/types.py`. The GUI layer is responsible for converting these back to QGIS layers if necessary. ### 5. Golden Rules for Thread-Safety * **Prohibited**: Importing `qgis.gui` inside `core/`. Background threads will crash if they attempt to touch any widget or window. * **Restriction**: Minimize the use of `qgis.core` inside `core/`. While some classes like `QgsGeometry` are thread-safe, it is preferable to operate on WKT to guarantee total independence. * **Application Context**: Never use `iface` or `QgsProject.instance()` inside `core/`. If project data is needed, pass it as pre-extracted arguments. --- ## 🧪 Differentiated Testing Strategy * **Core Tests (`tests/core/`)**: Must be able to run without a full QGIS installation. They use lightweight mocks. They are the thermometer of geological logic. * **Integration Tests (`tests/integration/`)**: Require real QGIS. They test that our "Core" correctly communicates with the "QGIS API". --- ## 🛠️ Decoupling Summary (January 2026) A major effort has been completed to ensure: * `GeologyService` does not use live QGIS layers in its processing method. * `DrillholeService` uses dictionaries instead of `QgsFeature` objects during trace calculation. * 3D projection logic accepts tuples and primitive types. **In summary: Keep our Core "pure". Treat QGIS as an external service provider. Do not let the roots of one enter the logic of the other.**