Architect and develop the DB Explorer project with Python backend and React frontend following hexagonal architecture
Build and maintain a full-stack database exploration tool with:
This skill provides comprehensive workflows, coding standards, and tools for developing both backend and frontend components while preserving architectural boundaries.
db-explorer/
├── README.md # Project overview and setup
├── docker-compose.yml # Container orchestration
├── .gitignore # Git ignore patterns
├── .pre-commit-config.yaml # Pre-commit hooks
│
├── backend/ # Python Backend (FastAPI)
│ ├── pyproject.toml # Poetry dependencies and config
│ ├── poetry.lock # Locked dependencies
│ ├── pytest.ini # Pytest configuration
│ ├── .env.example # Environment variables template
│ │
│ ├── src/ # Source code
│ │ ├── main.py # FastAPI application entry point
│ │ ├── config.py # Application configuration
│ │ │
│ │ ├── core/ # Domain Layer (Pure Python, no external deps)
│ │ │ ├── domain/ # Domain models and types
│ │ │ │ ├── types.py # UniversalDataType, value objects
│ │ │ │ └── models.py # Domain entities
│ │ │ └── ports/ # Port interfaces
│ │ │ └── database.py # DatabasePort interface
│ │ │
│ │ ├── application/ # Application Layer (Use Cases)
│ │ │ ├── query_executor.py # Query execution service
│ │ │ └── schema_reader.py # Schema reading service
│ │ │
│ │ └── adapters/ # Adapters Layer (External dependencies)
│ │ ├── driving/ # Driving adapters (API, CLI)
│ │ │ └── api/
│ │ │ └── v1/ # FastAPI routes
│ │ │ ├── queries.py
│ │ │ └── schemas.py
│ │ │
│ │ └── driven/ # Driven adapters (Database connectors)
│ │ ├── oracle.py # Oracle connector
│ │ ├── clickhouse.py # ClickHouse connector
│ │ ├── databricks.py # Databricks connector
│ │ └── factory.py # Connector factory
│ │
│ └── tests/ # Test suite
│ ├── conftest.py # Pytest fixtures
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── test_data/ # Test fixtures and data
│
├── web-ui/ # React TypeScript Frontend
│ ├── package.json # npm dependencies
│ ├── tsconfig.json # TypeScript configuration
│ ├── vite.config.ts # Vite build configuration
│ ├── .env.example # Environment variables template
│ ├── index.html # HTML entry point
│ ├── public/ # Static assets
│ │
│ └── src/ # Source code
│ ├── main.tsx # React entry point
│ ├── App.tsx # Root component
│ ├── vite-env.d.ts # Vite type definitions
│ │
│ ├── components/ # React components
│ │ ├── QueryEditor/ # SQL editor component
│ │ ├── SchemaExplorer/ # Schema browser component
│ │ └── ResultsTable/ # Results display component
│ │
│ ├── hooks/ # Custom React hooks
│ │ ├── useQuery.ts # Query execution hook
│ │ └── useSchema.ts # Schema fetching hook
│ │
│ ├── services/ # API service layer
│ │ ├── api.ts # Axios client setup
│ │ ├── queryService.ts # Query API calls
│ │ └── schemaService.ts # Schema API calls
│ │
│ ├── types/ # TypeScript type definitions
│ │ ├── query.ts # Query-related types
│ │ └── schema.ts # Schema-related types
│ │
│ ├── utils/ # Utility functions
│ └── styles/ # Global styles
│
└── skills/ # Claude Code skills
├── agent-architect/ # General agent skill
└── db-explorer-architect/ # This skill
├── SKILL.md # Main skill documentation
├── scripts/ # Automation scripts
│ ├── lint_backend.sh # Backend code quality
│ └── lint_frontend.sh # Frontend code quality
└── references/ # Reference documentation
├── architecture.md # Architecture rules
├── design-patterns.md # Design patterns
├── python-standards.md # Python coding standards
└── react-standards.md # React coding standards
Location: All Python code resides in the backend/ directory.
Entry Point: backend/src/main.py - FastAPI application
Architecture: Hexagonal (Ports & Adapters)
src/core/domain): Pure Python, zero external dependenciessrc/core/ports): Abstract interfaces (e.g., DatabasePort)src/application): Use cases orchestrating domain logic, including the CleaningEnginesrc/adapters): External integrations (FastAPI, databases)Data Flow (fetch → clean → serve):
API (FastAPI) → DataService → CleaningEngine → DatabasePort → Remote DB
DatabasePort fetches raw, unmodified rows from the remote database (read-only).CleaningEngine (src/application/cleaning_engine.py) transforms raw rows in memory:
NULL-like values.UniversalDataType values.Read-Only Enforcement:
DatabasePort implementation must use a read-only connection (e.g., SET TRANSACTION READ ONLY, readonly=True driver option, or a DB user with SELECT-only privileges).execute_safe_read method must parse the SQL statement and raise ReadOnlyViolationError if it detects INSERT, UPDATE, DELETE, DROP, ALTER, TRUNCATE, CREATE, or MERGE keywords before sending the query to the database.Adding New Database Connector:
backend/src/adapters/driven/[db-name].pyDatabasePort interface from src/core/ports/database.py; enforce read-only mode in connect().backend/src/adapters/driven/factory.pybackend/tests/integration/test_[db-name].pybackend/src/config.pyCode Quality Standards:
Configuration: backend/pyproject.toml
Commands (run from backend/ directory):
# Format code
black src/ tests/ --line-length 100
isort src/ tests/ --profile black
# Type check
mypy src/ --strict
# Lint
ruff check src/ tests/
# Test
pytest tests/ --cov=src --cov-report=term-missing
# All checks
../skills/db-explorer-architect/scripts/lint_backend.sh --fix
Location: All React code resides in the web-ui/ directory.
Entry Point: web-ui/src/main.tsx - React application root
Technology Stack:
Code Quality Standards:
Configuration: web-ui/tsconfig.json, web-ui/vite.config.ts
Commands (run from web-ui/ directory):
# Development server
npm run dev
# Lint
npm run lint # Check
npm run lint:fix # Auto-fix
# Format
npm run format # Fix formatting
npm run format:check # Check formatting
# Type check
npm run type-check
# Test
npm run test # Watch mode
npm run test:run # Single run
# Build
npm run build
# All checks
../skills/db-explorer-architect/scripts/lint_frontend.sh --fix
Adding New React Component:
web-ui/src/components/[ComponentName]/[ComponentName].tsx - Component implementation[ComponentName].module.css - Styles (optional)[ComponentName].test.tsx - Testsindex.ts - Barrel exportreferences/react-standards.md)Users can configure how fetched data is displayed and cleaned without touching the remote database. All rules are applied client-side or by the CleaningEngine in the backend.
Supported cleaning / view rules (examples):
NULL / empty are excluded from the displayed result set.TIMESTAMP / date columns are converted to ISO-8601 (YYYY-MM-DDTHH:mm:ssZ) before display.UniversalDataType when the connector returns an ambiguous type.How rules are applied (backend flow):
CleaningConfig alongside the SQL query.DataService forwards raw rows from DatabasePort to CleaningEngine.apply(rows, config).CleaningEngine applies each enabled rule in order and returns the cleaned List[UniversalRow].Frontend contract: the frontend always receives a UniversalFormat response — a list of objects with { column: string, type: UniversalDataType, value: any } entries — regardless of the source database.
Docker Setup:
docker-compose.yml at project rootEnvironment Configuration:
backend/.env (copied from .env.example)
DATABASE_URL=oracle://user:pass@host:port/service
LOG_LEVEL=INFO
CORS_ORIGINS=http://localhost:5173
web-ui/.env (copied from .env.example)
VITE_API_BASE_URL=http://localhost:8000/api/v1
API Communication:
http://localhost:8000/api/v1backend/src/main.py:
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:5173"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Deployment:
# Development
docker-compose up -d
# Backend only
cd backend && uvicorn src.main:app --reload
# Frontend only
cd web-ui && npm run dev
See references/python-standards.md for complete Python coding standards.
See references/react-standards.md for complete React/TypeScript coding standards.
See references/design-patterns.md for detailed pattern implementations.
scripts/lint_backend.sh: Run all backend quality checks
./skills/db-explorer-architect/scripts/lint_backend.sh [--fix]
Runs: Black, isort, Mypy, Ruff, Pytestscripts/lint_frontend.sh: Run all frontend quality checks
./skills/db-explorer-architect/scripts/lint_frontend.sh [--fix]
Runs: Prettier, ESLint, TypeScript check, Vitestscripts/test_all.sh: Run all tests (backend + frontend)scripts/docker_dev.sh: Start development environment with DockerComprehensive documentation for architecture, patterns, and coding standards:
references/architecture.md: Hexagonal architecture rules, layer dependencies, DatabasePort interface contract, streaming & transport requirements, security & secrets managementreferences/python-standards.md: Python coding standards including:
references/react-standards.md: React/TypeScript coding standards including:
references/design-patterns.md: Design pattern implementations:
Create Adapter (backend/src/adapters/driven/[db-name].py):
from src.core.ports.database import DatabasePort
class MyDBConnector(DatabasePort):
def connect(self) -> None: ...
def execute_query_stream(self, sql: str, params=None): ...
def fetch_schema(self, table: str): ...
Register in Factory (backend/src/adapters/driven/factory.py):
CONNECTORS = {
"mydb": MyDBConnector,
# ... other connectors
}
Add Configuration (backend/src/config.py):
class MyDBConfig(BaseModel):
host: str
port: int = 5432
database: str
Write Tests (backend/tests/integration/test_mydb.py):
def test_mydb_connection():
connector = MyDBConnector(config)
connector.connect()
assert connector.is_connected()
Define Route (backend/src/adapters/driving/api/v1/[resource].py):
@router.post("/queries/execute")
async def execute_query(request: QueryRequest):
result = query_executor.execute(request.sql)
return {"data": result}
Frontend Service (web-ui/src/services/queryService.ts):
export const executeQuery = async (sql: string): Promise<QueryResult> => {
const response = await api.post('/queries/execute', { sql });
return response.data;
};
React Hook (web-ui/src/hooks/useQuery.ts):
export const useQuery = () => {
const [data, setData] = useState<QueryResult | null>(null);
const execute = useCallback(async (sql: string) => {
const result = await executeQuery(sql);
setData(result);
}, []);
return { data, execute };
};
Create Component Directory:
web-ui/src/components/MyComponent/
├── MyComponent.tsx
├── MyComponent.module.css
├── MyComponent.test.tsx
└── index.ts
Implement Component (MyComponent.tsx):
import React from 'react';
import styles from './MyComponent.module.css';
interface MyComponentProps {
title: string;
onAction: () => void;
}
export const MyComponent: React.FC<MyComponentProps> = ({ title, onAction }) => {
return (
<div className={styles.container}>
<h2>{title}</h2>
<button onClick={onAction}>Action</button>
</div>
);
};
Add Tests (MyComponent.test.tsx):
import { render, screen, fireEvent } from '@testing-library/react';
import { MyComponent } from './MyComponent';
describe('MyComponent', () => {
it('calls onAction when button clicked', () => {
const mockAction = vi.fn();
render(<MyComponent title="Test" onAction={mockAction} />);
fireEvent.click(screen.getByRole('button'));
expect(mockAction).toHaveBeenCalled();
});
});
# Database Configuration
DATABASE_URL=oracle://user:password@host:1521/service
CLICKHOUSE_URL=http://localhost:8123
DATABRICKS_HOST=your-workspace.cloud.databricks.com
DATABRICKS_TOKEN=your-token
# Application Configuration
LOG_LEVEL=INFO
ENVIRONMENT=development
SECRET_KEY=your-secret-key
# CORS Configuration
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
# Security
MAX_QUERY_ROWS=10000
QUERY_TIMEOUT_SECONDS=300
# API Configuration
VITE_API_BASE_URL=http://localhost:8000/api/v1
# Feature Flags
VITE_ENABLE_QUERY_HISTORY=true
VITE_ENABLE_SCHEMA_EXPLORER=true
# Application Configuration
VITE_APP_TITLE=DB Explorer
VITE_MAX_RESULT_ROWS=1000
Clone Repository:
git clone https://github.com/your-org/db-explorer.git
cd db-explorer
Backend Setup:
cd backend
# Install Python 3.12+
# Install Poetry: https://python-poetry.org/docs/#installation
poetry install
cp .env.example .env
# Edit .env with your database credentials
# Run migrations (if applicable)
poetry run alembic upgrade head
# Start backend server
poetry run uvicorn src.main:app --reload
Frontend Setup:
cd web-ui
# Install Node.js 18+ and npm
npm install
cp .env.example .env
# Edit .env with your API URL
# Start development server
npm run dev
Access Application:
Create Feature Branch:
git checkout -b feature/your-feature-name
Make Changes: Follow coding standards for backend or frontend
Run Quality Checks:
# Backend
cd backend
../skills/db-explorer-architect/scripts/lint_backend.sh --fix
# Frontend
cd web-ui
../skills/db-explorer-architect/scripts/lint_frontend.sh --fix
Run Tests:
# Backend
cd backend && pytest tests/ -v
# Frontend
cd web-ui && npm run test:run
Commit and Push:
git add .
git commit -m "feat: add your feature"
git push origin feature/your-feature-name
Create Pull Request: Follow PR template guidelines