CLAUDE.md
unoplat-code-confluence-ingestion/code-confluence-flow-bridge/CLAUDE.mdCLAUDE.md
Quality
96/100
Scores the file, not the repository.Length
1,923 words
78 headings · 16 code blocksRepository
95
— · pushed 4 days agoLast changed
2 days ago
First indexed 2 days ago.1# Code Confluence Flow Bridge - Claude Code Integration Guide23## Agent Context45Also read `AGENTS.md` in this directory for auto-generated dependency guide, business logic domain map, and app interface inventory. Companion files `business_logic_references.md` and `app_interfaces.md` provide detailed module and endpoint references.67## Project Overview89Code Confluence Flow Bridge is the backend ingestion service for the Unoplat Code Confluence system. It orchestrates repository processing workflows using Temporal, parses code structures using Tree-sitter, and stores results in Neo4j graph and PostgreSQL relational databases.1011### Key Responsibilities12- **Workflow Orchestration**: Temporal-based workflows for repository and codebase processing13- **Code Parsing**: Language-agnostic parsing using Tree-sitter (Python and TypeScript support)14- **Graph Persistence**: Neo4j storage for code structure and relationships15- **Metadata Management**: PostgreSQL for workflow state, credentials, and configuration16- **Multi-language Support**: Framework detection and package manager analysis1718## Essential Development Commands1920### Dependency Management21```bash22# Sync dependencies (required before running)23task sync2425# Update a specific package26task update-package PACKAGE=package_name2728# Update all packages29task update-all-packages30```3132### Development Workflow33```bash34# Start all dependencies (PostgreSQL, Neo4j, Temporal, Elasticsearch)35task start-dependencies3637# Start only core dependencies (without Signoz/OpenTelemetry)38task start-core-dependencies3940# Run FastAPI server in development mode41task run-dev # Requires dependencies already running42task dev # Starts dependencies then runs FastAPI4344# Stop all dependencies45task stop-dependencies46task stop-core-dependencies47```4849### Testing & Code Quality50```bash51# Run tests with coverage52task test5354# Linting55task lint # Check with ruff56task lint-fix # Auto-fix issues5758# Type checking59task typecheck # Full type check60task typecheck-file FILE=path/to/file.py6162# Code formatting63task format # Format with ruff6465# Framework definition validation66task validate-framework-definitions67task validate-single-framework FILE=framework-definitions/python/fastapi.json68```6970### GitHub Integration71```bash72# Submit test job to flow bridge73task run-client # Uses CLI config to test ingestion7475# Run GitHub Actions locally76task run-github-action-locally77```7879## Architecture Overview8081### Service Architecture8283```84┌─────────────────────────────────────────────────────────────┐85│ FastAPI Application (main.py) │86│ - Token management endpoints │87│ - Repository discovery (GitHub GraphQL) │88│ - Ingestion orchestration │89│ - Status tracking and deletion │90└──────────────────────┬──────────────────────────────────────┘91 │92 ┌──────────────┼──────────────┐93 │ │ │94 ▼ ▼ ▼95 Temporal PostgreSQL Neo4j96 Workflows (Metadata) (Graph DB)97 │98 ┌────┴─────┬──────────┬──────────────┐99 │ │ │ │100 ▼ ▼ ▼ ▼101RepoWorkflow Git Package Codebase102 Activity Metadata Processing103 Activity Activity104```105106### Workflow Orchestration (Temporal)107108**Parent Workflow**: `RepoWorkflow` (class-based)109- Orchestrates entire repository ingestion process110- Manages child workflows for each codebase111- Task Queue: `unoplat-code-confluence-repository-context-ingestion`112113**Key Activities** (executed by worker pool):1141. **GitActivity** - Clones repository, extracts metadata1152. **ConfluenceGitGraph** - Inserts repository structure into Neo4j1163. **PackageMetadataActivity** - Extracts dependency information1174. **PackageManagerMetadataIngestion** - Stores package data in Neo4j1185. **GenericCodebaseProcessingActivity** - Parses code and creates graph nodes1196. **ChildWorkflowDbActivity** - Updates codebase workflow status in PostgreSQL1207. **ParentWorkflowDbActivity** - Updates repository workflow status in PostgreSQL121122**Child Workflow**: `CodebaseChildWorkflow`123- Processes individual codebases detected in repository124- Handles language-specific parsing and metadata extraction125126### Data Flow1271281. **Repository Discovery**129 - Frontend requests repository list via GraphQL130 - Backend fetches from GitHub (GITHUB_OPEN or GITHUB_ENTERPRISE)131 - Credentials encrypted/stored in PostgreSQL1321332. **Codebase Detection**134 - Auto-detection using multi-language ripgrep detectors135 - Supported: Python (PythonRipgrepDetector), TypeScript (TypeScriptRipgrepDetector)136 - Returns: List of CodebaseConfig with metadata1371383. **Ingestion Workflow**139 - Temporal workflow clones repository to `/opt/unoplat/repositories`140 - GitActivity creates UnoplatGitRepository structure141 - ConfluenceGitGraph inserts repository node into Neo4j142 - Child workflows spawn for each detected codebase1431444. **Code Parsing**145 - GenericCodebaseParser uses language processors146 - Tree-sitter extracts structural signatures147 - Framework detection (Python: FastAPI, Django, Flask, etc.)148 - Package manager parsing (pip, uv, poetry, npm, yarn, etc.)1491505. **Persistence**151 - PostgreSQL: Workflow runs, credentials, framework definitions152 - Neo4j: Repository, File, Class, Function, Package nodes with relationships153154### Database Configuration155156**PostgreSQL** (via SQLAlchemy async + asyncpg)157- Connection URL: `postgresql+asyncpg://user:password@host:port/db`158- Session management: Per-loop async engine pattern (see `db.py`)159- Models: SQLBase from commons (Repository, CodebaseConfig, RepositoryWorkflowRun, CodebaseWorkflowRun)160161**Neo4j** (via neomodel + neo4j driver)162- Connection URL: `bolt://user:password@host:port`163- Uses async driver for non-blocking operations164- Global connection via `CodeConfluenceGraph` singleton165- Schema: Installed at startup via `adb.install_all_labels()`166167**Environment Variables** (from `EnvironmentSettings`):168```python169# PostgreSQL170DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME171172# Neo4j173NEO4J_HOST, NEO4J_PORT, NEO4J_USERNAME, NEO4J_PASSWORD174NEO4J_MAX_CONNECTION_LIFETIME, NEO4J_MAX_CONNECTION_POOL_SIZE175NEO4J_CONNECTION_ACQUISITION_TIMEOUT176177# Temporal178TEMPORAL_SERVER_ADDRESS (default: localhost:7233)179TEMPORAL_MAX_CONCURRENT_ACTIVITIES (default: 4)180TEMPORAL_ENABLE_POLLER_AUTOSCALING (default: false)181182# Repositories183REPOSITORIES_BASE_PATH (default: ~/.unoplat/repositories)184185# Framework definitions186FRAMEWORK_DEFINITIONS_PATH (default: /framework-definitions)187```188189## Important Architecture Patterns190191### 1. Envelope Pattern (Temporal Parameters)192193All Temporal workflow/activity parameters are wrapped in envelope models to handle extra fields:194195```python196# Example: RepoWorkflowRunEnvelope197@dataclass198class RepoWorkflowRunEnvelope(BaseModel):199 repo_request: RepositoryRequestConfiguration # Main payload200 github_token: str201 trace_id: str202 model_config = ConfigDict(extra="allow") # Allow extra fields203204 @property205 def extras(self) -> dict[str, Any]:206 return dict(self.model_extra or {})207```208209All envelope models support `extra="allow"` to handle Pydantic data converter requirements.210211### 2. Async Database Session Management212213Critical pattern for handling multiple event loops:214215```python216# Gets or creates AsyncEngine per event loop217engine, session_factory = await get_engine_for_loop()218219# Yields session for dependency injection220async def get_session() -> AsyncGenerator[AsyncSession, None]:221 async with session_factory() as session:222 async with session.begin(): # Explicit transaction223 yield session224 # Commit on __exit__, rollback on exception225226# For context managers (activities)227async with get_session_cm() as session:228 await session.execute(...) # Auto-committed on context exit229```230231**Key Points**:232- Each event loop gets its own AsyncEngine (fixes Temporal activity issues)233- `expire_on_commit=False` critical for async (prevents implicit I/O)234- Always use `async with session.begin()` for explicit transactions235- Activities in Temporal need context manager pattern for cleanup236237### 3. Temporal Worker Configuration238239Worker handles both parent and child workflows with interceptors:240241```python242worker = Worker(243 client,244 task_queue="unoplat-code-confluence-repository-context-ingestion",245 workflows=[RepoWorkflow, CodebaseChildWorkflow],246 activities=activities,247 activity_executor=ThreadPoolExecutor(size=max_concurrent + 4),248 interceptors=[249 ParentWorkflowStatusInterceptor(), # Updates parent workflow status250 ActivityStatusInterceptor(), # Updates activity status251 ],252 max_concurrent_activities=env.temporal_max_concurrent_activities,253)254```255256### 4. Parser Factory Pattern257258Language-specific parsing via strategy pattern:259260```python261# Generic parser delegates to language-specific processors262parser = GenericCodebaseParser(263 codebase_name="my-app",264 codebase_path="/repo/src",265 language_metadata=ProgrammingLanguageMetadata(...),266)267268# Internally uses:269# - PythonLanguageProcessor (wraps TreeSitterPythonStructuralSignatureExtractor)270# - TypeScriptLanguageProcessor271# - Custom processors for other languages272```273274### 5. Package Manager Strategy275276Different strategies for different package managers:277278```python279# Strategy pattern for package manager processing280class PackageManagerStrategy(ABC):281 @abstractmethod282 def process_metadata(283 self,284 local_workspace_path: str,285 metadata: ProgrammingLanguageMetadata286 ) -> UnoplatPackageManagerMetadata:287 pass288```289290Implementations available for: pip, uv, poetry, npm, yarn, maven, etc.291292### 6. Neo4j Session Management293294Uses neomodel's managed transactions pattern:295296```python297# Get session from global connection298async with code_confluence_graph.get_session() as neo4j_session:299 # Use session.execute_write() or execute_read() for managed transactions300 result = await neo4j_session.execute_write(some_function, arg1, arg2)301```302303Automatic retry and transaction management via Neo4j driver.304305### 7. Logging & Tracing306307Distributed tracing with Loguru and OpenTelemetry:308309```python310# ContextVar-based trace propagation311from code_confluence_flow_bridge.logging.trace_utils import (312 trace_id_var,313 workflow_id_var,314 activity_name_var,315)316317# Bind trace context to logger318log = seed_and_bind_logger_from_trace_id(319 trace_id=trace_id,320 workflow_id=workflow_id,321 workflow_run_id=run_id322)323324# Logs include trace context automatically325log.info("Processing started", extra={"activity": "git_clone"})326```327328Optional OTLP export to SigNoz when `OTEL_EXPORTER_OTLP_ENDPOINT` is set.329330### 8. Error Handling Pattern331332Standardized error context for debugging:333334```python335try:336 # Operation337except Exception as e:338 error_context = {339 "workflow_id": workflow_id,340 "activity_name": "process_git",341 "error_details": str(e),342 "traceback": traceback.format_exc(),343 }344 logger.error("Operation failed: {}", str(e), extra={"error_context": error_context})345 # Re-raise as ApplicationError for Temporal346 raise ApplicationError(str(e), type="CUSTOM_ERROR_TYPE") from e347```348349## Key Directory Structure350351```352src/code_confluence_flow_bridge/353├── main.py # FastAPI app, lifespan, endpoints354├── logging/355│ ├── log_config.py # Loguru + OTLP setup356│ └── trace_utils.py # ContextVar-based trace propagation357├── models/358│ ├── configuration/359│ │ └── settings.py # EnvironmentSettings (all env vars)360│ ├── github/361│ │ └── github_repo.py # Request/response models362│ ├── workflow/363│ │ └── repo_workflow_base.py # Envelope models364│ └── code_confluence_parsing_models/365│ ├── unoplat_git_repository.py366│ ├── unoplat_package_manager_metadata.py367│ └── unoplat_file.py368├── processor/ # Temporal workflows & activities369│ ├── repo_workflow.py # Parent workflow orchestration370│ ├── codebase_child_workflow.py # Child workflow for each codebase371│ ├── db/372│ │ ├── postgres/373│ │ │ ├── db.py # AsyncEngine & session management374│ │ │ ├── parent_workflow_db_activity.py375│ │ │ ├── child_workflow_db_activity.py376│ │ │ └── framework_loader.py377│ │ └── graph_db/378│ │ ├── code_confluence_graph.py # Neo4j connection379│ │ ├── code_confluence_graph_ingestion.py380│ │ └── code_confluence_graph_deletion.py381│ ├── git_activity/382│ │ ├── confluence_git_activity.py # Clones repo activity383│ │ └── confluence_git_graph.py # Inserts into Neo4j384│ ├── package_metadata_activity/ # Package extraction385│ └── activity_*.py # Interceptors for status updates386├── parser/387│ ├── generic_codebase_parser.py # Main parser (delegates to processors)388│ ├── tree_sitter_*.py # Tree-sitter utilities389│ ├── language_processors/390│ │ ├── base.py # Abstract processor391│ │ ├── python_processor.py392│ │ └── typescript_processor.py393│ └── package_manager/394│ ├── package_manager_strategy.py395│ ├── package_manager_factory.py396│ └── detectors/ # Codebase detection397├── detector/398│ ├── base_detector.py399│ └── ripgrep_*.py # Ripgrep-based detection400├── engine/401│ ├── framework_detection_service.py402│ ├── python/403│ │ └── python_framework_detection_service.py404│ └── generic_filters.py405└── github_app/406 └── router.py # GitHub App webhook endpoints407```408409## Common Development Workflows410411### Adding a New Framework4124131. Add framework definition JSON to `framework-definitions/{language}/framework-name.json`4142. Validate: `task validate-single-framework FILE=...`4153. Framework loaded automatically at startup via `FrameworkDefinitionLoader`416417### Implementing Language Support4184191. Create `LanguageCodebaseProcessor` subclass in `parser/language_processors/`4202. Implement Tree-sitter extraction via `TreeSitterExtractorBase`4213. Register in `GenericCodebaseParser.LANGUAGE_PROCESSORS` mapping4224. Add detector (ripgrep-based) in `detector/`4235. Add to `main.py` lifespan detectors registration424425### Testing Ingestion Locally426427```bash428# Terminal 1: Start dependencies429task start-dependencies430431# Terminal 2: Run development server432task run-dev433434# Terminal 3: Submit test job435task run-client436437# Monitor: Check Temporal UI at http://localhost:8081438```439440### Debugging Workflows4414421. Check Temporal UI for workflow execution history: http://localhost:80814432. View Neo4j graph: http://localhost:7474 (default: neo4j/password)4443. Check PostgreSQL: `psql -U postgres -h localhost -d code_confluence`4454. Check logs with trace ID: Search for `trace_id` in logs446447## Critical Implementation Notes448449### Async/Await Best Practices450451- Always use `async with` for database sessions452- Never use `.result()` on coroutines in sync context453- Use `asyncio.create_task()` for fire-and-forget background work (e.g., `monitor_workflow()`)454- ThreadPoolExecutor required for Temporal activities (can't run pure async code)455456### Type Safety457458- Use `type: ignore` for dynamic models from commons (Credentials, Repository, etc.)459- Enable strict type checking: `pyrefly` with `preset = "strict"`460- Always define return types for activities (required by Temporal)461462### Neo4j Transactions463464- Always use `session.execute_write()` or `execute_read()` for managed transactions465- Don't use raw `session.run()` in activities (no retry)466- Batch operations with UNWIND for performance (see `codebase_parser_*_batch_size`)467468### PostgreSQL Sessions469470- Never commit manually in activity - use context manager471- Use `session.begin()` explicitly for transaction control472- Cascade deletes work via SQLAlchemy relationships473474### Performance Optimization475476- File batch processing: `CODEBASE_PARSER_FILE_BATCH_SIZE` (default 1000)477- Package batch processing: `CODEBASE_PARSER_PACKAGE_BATCH_SIZE` (default 500)478- Concurrent file parsing: `CODEBASE_PARSER_FILE_PROCESSING_CONCURRENCY` (default 3)479- Activity concurrency: `TEMPORAL_MAX_CONCURRENT_ACTIVITIES` (default 4)480481## Environment Variables Summary482483### Required at Startup484- `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`485- `NEO4J_HOST`, `NEO4J_PORT`, `NEO4J_USERNAME`, `NEO4J_PASSWORD`486- `TEMPORAL_SERVER_ADDRESS`487488### Optional with Defaults489- `REPOSITORIES_BASE_PATH` → `~/.unoplat/repositories`490- `FRAMEWORK_DEFINITIONS_PATH` → `/framework-definitions`491- `LOG_LEVEL` → `DEBUG`492- `ALLOWED_ORIGINS` → `http://localhost:5173` (CORS)493494### Feature Flags495- `OTEL_EXPORTER_OTLP_ENDPOINT` → Enable OpenTelemetry export496- `LOAD_FRAMEWORK_DEFINITIONS` → Load framework definitions at startup (default: true)497- `FRAMEWORK_DEFINITIONS_REQUIRED` → Fail startup if loading fails (default: false)498- `DB_ECHO` → Log all SQL (default: false)499500## Integration with Commons501502The project uses `unoplat-code-confluence-commons` for shared models:503- `Credentials` - Encrypted token storage504- `Repository`, `CodebaseConfig` - Repository metadata505- `RepositoryWorkflowRun`, `CodebaseWorkflowRun` - Workflow execution records506- `ProgrammingLanguageMetadata` - Language-specific config507- `Flag` - Feature flags508509Reference via absolute imports: `from unoplat_code_confluence_commons.base_models import ...`510511---512513**Last Updated**: 2025-11-14514**Python Version**: 3.13+515**Package Manager**: uv516517518<CRITICAL_INSTRUCTION>519520## Backlog Workflow521522This project uses Backlog.md MCP for all task and project management. **Before creating tasks or tracking work, read [`backlog_instructions.md`](./backlog_instructions.md)** for the complete workflow guidance.523524</CRITICAL_INSTRUCTION>525
Also in unoplat/unoplat-code-confluence
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| unoplat/unoplat-code-confluenceAGENTS.md · 95 | AGENTS.md | testlint-formatmonorepoagent-behaviour | 48/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-cli/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+3 | 84/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-commons/.cursor/rules/use-think-tool.mdc · 95 | Cursor rules | no sections | 30/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-commons/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+2 | 88/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-docs/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+3 | 75/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-docs/CLAUDE.md · 95 | CLAUDE.md | testgitagent-behaviour | 43/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-frontend/.cursor/rules/react-vite-tanstack.mdc · 95 | Cursor rules | styleagent-behaviour | 38/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-frontend/.cursor/rules/shadcn-tanstack-knowledge.mdc · 95 | Cursor rules | teststyleuiperformance | 48/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-frontend/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-frontend/CLAUDE.md · 95 | CLAUDE.md | setupstylearchui+1 | 62/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-ingestion/code-confluence-flow-bridge/.cursor/rules/code-structure.mdc · 95 | Cursor rules | no sections | 16/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-ingestion/code-confluence-flow-bridge/.cursor/rules/fastapi-pydantic.mdc · 95 | Cursor rules | styletypes | 38/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-ingestion/code-confluence-flow-bridge/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+3 | 77/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-openmetadata/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+2 | 79/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-query-engine/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+5 | 98/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-query-engine/CLAUDE.md · 95 | CLAUDE.md | agent-behaviour | 25/100 | 2 days ago |
Diff against AGENTS.md Diff against unoplat-code-confluence-cli/AGENTS.md Diff against unoplat-code-confluence-commons/.cursor/rules/use-think-tool.mdc Diff against unoplat-code-confluence-commons/AGENTS.md Diff against unoplat-code-confluence-docs/AGENTS.md Diff against unoplat-code-confluence-docs/CLAUDE.md Diff against unoplat-code-confluence-frontend/.cursor/rules/react-vite-tanstack.mdc Diff against unoplat-code-confluence-frontend/.cursor/rules/shadcn-tanstack-knowledge.mdc Diff against unoplat-code-confluence-frontend/AGENTS.md Diff against unoplat-code-confluence-frontend/CLAUDE.md Diff against unoplat-code-confluence-ingestion/code-confluence-flow-bridge/.cursor/rules/code-structure.mdc Diff against unoplat-code-confluence-ingestion/code-confluence-flow-bridge/.cursor/rules/fastapi-pydantic.mdc Diff against unoplat-code-confluence-ingestion/code-confluence-flow-bridge/AGENTS.md Diff against unoplat-code-confluence-openmetadata/AGENTS.md Diff against unoplat-code-confluence-query-engine/AGENTS.md Diff against unoplat-code-confluence-query-engine/CLAUDE.md
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| Adit-Jain-srm/NightmareNetCLAUDE.md · 45 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 3 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 3 days ago | |
| microsoft/playwrightCLAUDE.md · 94k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 3 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.4k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 3 days ago | |
| dotCMS/coreCLAUDE.md · 949 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | today | |
| lollipopkit/flutter_server_boxCLAUDE.md · 8.3k | CLAUDE.md | buildteststylearch+2 | 98/100 | 3 days ago | |
| khrnchn/sedekah-jeCLAUDE.md · 89 | CLAUDE.md | testlint-formatstylearch+6 | 97/100 | 3 days ago | |
| luongnv89/claude-howtovi/CLAUDE.md · 41k | CLAUDE.md | setupbuildtestlint-format+8 | 97/100 | 3 days ago |
