refactor: architecture ports and split god modules - #15
Draft
jeremiepas wants to merge 4 commits into
Draft
Conversation
added 4 commits
July 28, 2026 14:29
Split Domain.Config (677 lines) into: - Domain.Config.Core (97 lines) — GraphosConfig, defaults, merge - Domain.Config.Extraction (284 lines) — ExtractorMode, Granularity, LSPServerConfig, defaults - Domain.Config.Export (89 lines) — Neo4jConfig, MemgraphConfig, defaults - Domain.Config.Observability (108 lines) — ObservabilityConfig, OtelConfig, defaults - Domain.Config.Vision (135 lines) — VisionConfig, EmbeddingConfig, LabelingConfig, defaults Original Domain.Config becomes a backward-compatible re-export module. All existing imports continue to compile without changes. Part of refactor-architecture-ports-and-split-god-modules (Task 1/12).
Add UseCase.Port.* record-of-functions interfaces: - ExtractionPort: extractAll, extractGroup, extractViaLSP, extractFromFile, extractImageFile, extractImageBytes, extractChanged - ExportPort: exportAll + ExportResult type - FileSystemPort: load/save/clear checkpoint, load ignore patterns - LoggingPort: logTrace/Debug/Info/Warn/Error + LogLevel enum - ObservabilityPort: init, shutdown, incCounter, setGauge, traceEvent - LLMPort: callLLM, parseLabels, generateEmbedding, analyzeImage, validateUrl + ImageAnalysis/ImageKind types Add UseCase.AppEnv: aggregates all 6 ports as single DI mechanism. All signatures reference only Domain types — no Infrastructure imports in port signatures (FileSystemPort imports AnnotatedPattern as transitional). Build passes, 199/200 tests pass (1 pre-existing flaky test).
…complete) - Infrastructure.Wiring: production composition root that creates AppEnv with concrete implementations for all 6 ports - ExtractionPort: refined with fine-grained LSP/TreeSitter primitives, LSPHandle uses Dynamic for opaque type safety - LLMPort: fixed ImageKind (added OtherKind), Entity type, CommunityId - FileSystemPort: imports PipelineCheckpoint from Domain.Types.Pipeline - ExportPort: imports from Domain.Types (not Domain.Config) - ObservabilityPort: fixed field names (otelMetrics/otelDebugTrace) - All 6 ports compile, Wiring compiles, 199/200 tests pass Note: ExportPort.epExportAll is TODO (will wire once UseCase.Export is refactored to use ports). ExtractionPort uses unsafeCoerce for LSPHandle -> LSPClient conversion (safe: only Wiring creates handles).
…ture (Task 6 partial) - UseCase.Extract: replaced ALL Infrastructure imports with port calls - extractAll, extractChangedFiles, extractFromFile now take AppEnv - LSP calls go through extractionPort (epConnectLSP, epExtractViaLSP, etc.) - Logging goes through loggingPort (lpLogInfo, lpLogDebug, etc.) - Neo4j streaming goes through epPushExtractionStreaming - TreeSitter goes through epParseWithGrammar - Office/image extraction goes through epExtractDocFile, etc. - Zero Infrastructure imports in UseCase.Extract! - UseCase.Pipeline: added appEnv creation via productionAppEnv - extractAll, extractChangedFiles now receive AppEnv - ingestFile now receives AppEnv - UseCase.Ingest: added AppEnv parameter to ingestFile - Calls Extract.extractAll with AppEnv Build passes, 199/200 tests pass (pre-existing flaky test). Note: UseCase.Pipeline, Ingest, Label, Detect, Export, and Extract sub-modules still have Infrastructure imports. Full migration is Tasks 7-8.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactor: Architecture Ports and Split God Modules
Why
31 UseCase→Infrastructure import violations break clean architecture. Three god modules (UseCase.Extract 657 lines, UseCase.Pipeline 588 lines, Domain.Config 677 lines) hurt comprehension, testability, and evolution. Main.hs (718 lines) directly wires Infrastructure to UseCase without abstraction.
What Changes
UseCase.Port.*record-of-functions decoupling UseCase from InfrastructureProgress
Verification
cabal buildpassescabal testpasses (199/200 — 1 pre-existing flaky SDKSpec test)openspec validate --changesruns in CI (advisory, non-blocking)OpenSpec Artifacts
openspec/changes/refactor-architecture-ports-and-split-god-modules/— proposal, design, specs, tasks