docs: consolidate LESSONS-LEARNED.md into CLAUDE.md, single source of truth
Merged 8 unique lessons (#30-#37) from LESSONS-LEARNED.md into CLAUDE.md: Alembic env.py imports, JSONB datetime serialization, export pipeline order, Railway deployment gotchas, bcrypt pinning, email validator TLD, first admin promotion. Deleted LESSONS-LEARNED.md and updated all references. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
22
CLAUDE.md
22
CLAUDE.md
@@ -114,7 +114,7 @@ patherly/
|
||||
│ └── tailwind.config.js
|
||||
├── CLAUDE.md # This file
|
||||
├── CURRENT-STATE.md # Detailed feature status
|
||||
├── LESSONS-LEARNED.md # Bugs and fixes (READ THIS!)
|
||||
├── LESSONS-LEARNED.md # (Deprecated — consolidated into CLAUDE.md)
|
||||
└── docs/plans/ # Design docs & implementation plans
|
||||
```
|
||||
|
||||
@@ -194,8 +194,6 @@ gh run view <id> --json jobs --jq '.jobs[] | {name: .name, conclusion: .conclusi
|
||||
|
||||
## Critical Lessons Learned
|
||||
|
||||
**Full reference:** [LESSONS-LEARNED.md](LESSONS-LEARNED.md) — read before making changes!
|
||||
|
||||
### Top Gotchas (most commonly hit)
|
||||
|
||||
**1. DateTime Handling — Always timezone-aware:**
|
||||
@@ -290,6 +288,22 @@ navigate(`/trees/${newTree.id}/edit`)
|
||||
|
||||
**29. ESLint `no-unused-vars` has no `argsIgnorePattern`:** Underscore-prefixed callback params (e.g., `_count`) still trigger errors. Use `// eslint-disable-next-line @typescript-eslint/no-unused-vars` or remove the param if the type signature allows it.
|
||||
|
||||
**30. Alembic `env.py` must import all models:** New models won't be discovered by `--autogenerate` unless imported in `alembic/env.py`. If a migration runs but the table isn't created, check imports first.
|
||||
|
||||
**31. JSONB fields — convert datetime to `.isoformat()` string:** Storing `datetime` objects directly in JSONB columns causes serialization errors. Always convert: `"timestamp": datetime.now(timezone.utc).isoformat()`.
|
||||
|
||||
**32. Export pipeline order matters:** Generate export → resolve session variables → apply redaction. Redaction MUST run last or sensitive data injected via variables bypasses it. See `sessions.py` export endpoint.
|
||||
|
||||
**33. Railway: `DATABASE_URL_SYNC` is a property, not an env var:** It derives from `DATABASE_URL` by replacing `postgresql+asyncpg://` with `postgresql://`. Delete any stale `DATABASE_URL_SYNC` variable in Railway dashboard.
|
||||
|
||||
**34. Railway: run migrations in Docker CMD, not `releaseCommand`:** `releaseCommand` in `railway.toml` is unreliable. Use `CMD alembic upgrade head && uvicorn ...` in the Dockerfile instead.
|
||||
|
||||
**35. `bcrypt==4.0.1` pinned for passlib compatibility:** Newer bcrypt versions break password hashing. Keep `bcrypt==4.0.1` and `passlib[bcrypt]==1.7.4` pinned in `requirements.txt`.
|
||||
|
||||
**36. Email validator rejects `.local` TLD:** Pydantic's email validation (via `email-validator`) rejects `.local` as a reserved TLD. Use `example.com` for test/seed user emails.
|
||||
|
||||
**37. First deployed user needs manual admin promotion:** New users default to `engineer` role. Promote via SQL: `UPDATE users SET role = 'admin' WHERE email = '...';` then re-login for new JWT.
|
||||
|
||||
---
|
||||
|
||||
## RBAC & Permissions
|
||||
@@ -392,6 +406,6 @@ When a feature, fix, or significant piece of work is finished and merged/committ
|
||||
| Detailed Status | [CURRENT-STATE.md](CURRENT-STATE.md) |
|
||||
| Development Roadmap | [03-DEVELOPMENT-ROADMAP.md](03-DEVELOPMENT-ROADMAP.md) |
|
||||
| GitHub Issues | `gh issue list --state open` |
|
||||
| Bugs & Fixes | [LESSONS-LEARNED.md](LESSONS-LEARNED.md) |
|
||||
| Bugs & Fixes | CLAUDE.md → Critical Lessons Learned section |
|
||||
| Feature Specs | [04-FEATURE-SPECIFICATIONS.md](04-FEATURE-SPECIFICATIONS.md) |
|
||||
| Design System | [docs/plans/Frontend/DESIGN_SYSTEM_GUIDE.md](docs/plans/Frontend/DESIGN_SYSTEM_GUIDE.md) |
|
||||
|
||||
Reference in New Issue
Block a user