# Core Component Distinction Guide

This document aims to clarify the distinction between the different components named “Core” 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 Core):

   - Location: `/core` directory within the project root.

   - Purpose: Contains pure business logic, geological algorithms, processing services, and SecInterp-specific data models (DTOs).

   - Current Status: Decoupled. As of version 2.8.0, this module has been sanitized to have no direct dependencies on live QGIS 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 on the main thread, but SecInterp Core processes this data using agnostic types (WKT, dicts, primitives).

## 🧭 Rules for Developers and AI

To maintain architectural integrity, follow these guidelines:

### 1. Do Not Assume “Core” Always Means QGIS

When asked to “review the core,” this almost exclusively refers to the `/core` directory of this plugin. Do not attempt to search for or modify internal QGIS engine files.

### 2. Data Boundaries (Decoupling)

- In `/core`: Use agnostic domain types. Avoid instantiating `QgsVectorLayer` or accessing `QgsProject.instance()` within core services. Use `DomainGeometry` (WKT) and attribute dictionaries.

- In `/gui`: This is where the translation between the real QGIS API (`qgis.core`) and SecInterp Core takes place. This is where geometries are extracted and DTOs are prepared.

### 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 needed (geometry in WKT, attribute dictionaries).

2. Core Layer: Receives only the extracted data (strings, dicts, floats). Performs heavy geometric calculations.

3. Result: Core returns DTOs (Data Transfer Objects) defined in `core/types.py`. The GUI layer handles converting these back to QGIS layers if needed.

### 5. Golden Rules of Thread-Safety

- Forbidden: Import `qgis.gui` inside `core/`. Background threads will die if they attempt to touch any widget or window.

- Restriction: Minimize the use of `qgis.core` inside `core/`. Although some classes like `QgsGeometry` are safe, it is preferable to operate on WKT to ensure full independence.

- Application Context: Never use `iface` or `QgsProject.instance()` inside `core/`. If you need project data, 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 verify that our “Core” communicates correctly with the “QGIS API”.

## 🛠️ Decoupling Summary (January 2026)

A major effort has been completed to ensure that:

- `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 allow the roots of one to enter the logic of the other.