refactor: delete stale files and consolidate .mindmodel structure

Deleted stale root-level Python files:
- main.py (unused 'Hello world' script)
- verify.py (unused table info script)
- scraper.py (unused MotionScraper class)
- scheduler.py (unused DataUpdateScheduler class)

Deleted duplicate .mindmodel root YAML files (subdirectory versions are more comprehensive):
- anti-patterns.yaml, architecture.yaml, conventions.yaml
- dependencies.yaml, domain.yaml, domain-glossary.yaml
- stack.yaml, tech-stack.yaml, workflows.yaml

Added comprehensive .mindmodel subdirectories:
- constraints/ (naming, db-schema, error-handling, types, etc.)
- patterns/ (api, architecture, database, python, streamlit, etc.)
- examples/ (code examples for each pattern)
- anti-patterns/, architecture/, conventions/, dependencies/, domain/, stack/

Updated ARCHITECTURE.md to reflect current codebase:
- Removed references to non-existent files
- Added missing files (explorer.py, explorer_helpers.py, pipeline/)
- Added directory structure documentation
- Updated tech stack to include scipy, sklearn, umap

Updated .gitignore:
- Added patterns for generated analysis files
- Added .worktrees/ pattern (was already in gitignore but dir was deleted)

Removed empty .worktrees/ directory
This commit is contained in:
2026-04-04 18:46:53 +02:00
parent 0308d20f12
commit f376300804
22 changed files with 3824 additions and 48 deletions
+124
View File
@@ -0,0 +1,124 @@
# Naming Conventions
## Files
- **snake_case** for all Python files: `database.py`, `explorer_helpers.py`, `motion_cache.py`
- **PascalCase** NOT used for files
## Functions
- **snake_case**: `get_svd_vectors()`, `compute_party_coords()`, `build_scatter_trace()`
- Private helpers prefixed with `_`: `_get_window_data()`
## Classes
- **PascalCase**: `MotionDatabase`, `Config`
- **Dataclass pattern** for Config: `@dataclass` decorator with typed fields
## Variables
- **snake_case**: `party_map`, `mp_name`, `svd_vectors`, `party_centroids`
- **CONSTANT_SNAKE_CASE** for module-level constants: `PARTY_COLOURS`, `DEFAULT_WINDOW`
## Module-Level Exports
- **Singleton instance**: `db = MotionDatabase()` at module bottom (not class-level)
- **Config instance**: `config = Config(...)` at module bottom
- **Dicts**: `PARTY_COLOURS` exported from `config.py`
---
# Error Handling
## Known Patterns
1. **Bare except with pass** (ANTI-PATTERN - see anti-patterns.yaml)
```python
except:
pass # database.py:47
```
2. **Graceful degradation**: catch specific exceptions, fall back to default
```python
try:
result = compute_svd()
except ImportError:
result = DEFAULT_SVD
```
3. **Optional dependency fallbacks**:
```python
try:
import umap
use_umap = True
except ImportError:
use_umap = False
```
4. **Nested exception handling** (ANTI-PATTERN - see anti-patterns.yaml):
```python
try:
...
except Exception:
try:
...
except Exception:
pass
```
## Rules
- Never use bare `except:` — always specify exception type
- Never swallow exceptions silently — log or return a sensible default
- For optional deps, use `ImportError` or `ModuleNotFoundError` explicitly
- Avoid nested try/except blocks
---
# Code Organization
## Singleton Pattern
Each module owns one shared instance:
```python
# database.py
db = MotionDatabase()
# config.py
config = Config(...)
PARTY_COLOURS = {...}
```
## Pure Functions in Helpers
`explorer_helpers.py` contains only pure functions (no IO, no Streamlit calls):
```python
def compute_party_coords(svd_vectors, party_map):
"""Pure: no side effects, no imports from this module"""
...
def build_scatter_trace(df, color_col):
"""Pure: returns Plotly trace dict"""
...
```
## Cached Data Loaders
Use `@st.cache_data` for expensive data loading:
```python
@st.cache_data
def load_svd_vectors(window: str) -> pd.DataFrame:
return db.get_svd_vectors(window)
```
## Dataclass Config
```python
@dataclass
class Config:
db_path: str = "data/stemwijzer.duckdb"
default_window: str = "2023"
party_colours: dict = field(default_factory=lambda: PARTY_COLOURS)
```
---
# Imports
## Ordering (convention)
1. Standard library
2. Third-party (streamlit, ibis, plotly, sklearn, umap)
3. Local/relative imports
## Avoid
- Wildcard imports (`from module import *`)
- Circular imports (ensure dependency direction: helpers → database → config)