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:
SecInterp Core (The Project Core):
Location:
/coredirectory 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).
QGIS Core (The QGIS API):
Reference:
qgis.corePython package.Purpose: Provides the underlying geospatial infrastructure (geometries, layers, projects, CRS).
Interaction: SecInterp uses
qgis.coreto 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 instantiatingQgsVectorLayeror accessingQgsProject.instance()within core services. UseDomainGeometry(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, orqgis.utilsare External Dependencies.Naming Rule: In discussions or code comments, use “Internal Core” to refer to
/coreand “PyQGIS API” for the software’s API.
4. The “Extract-then-Compute” Pattern
To avoid future complications, the data flow MUST follow this pattern:
GUI/Task Interface Layer: Receives QGIS objects (
QgsVectorLayer,QgsFeature). Extracts what is needed (geometry in WKT, attribute dictionaries).Core Layer: Receives only the extracted data (strings, dicts, floats). Performs heavy geometric calculations.
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.guiinsidecore/. Background threads will die if they attempt to touch any widget or window.Restriction: Minimize the use of
qgis.coreinsidecore/. Although some classes likeQgsGeometryare safe, it is preferable to operate on WKT to ensure full independence.Application Context: Never use
ifaceorQgsProject.instance()insidecore/. 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:
GeologyServicedoes not use live QGIS layers in its processing method.DrillholeServiceuses dictionaries instead ofQgsFeatureobjects 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.