A personal knowledge management system implementing Tiago Forte's "Building a Second Brain" methodology.
- PARA Organization - Projects, Areas, Resources, Archives taxonomy
- CODE Workflow - Capture, Organize, Distill, Express stages
- Progressive Summarization - Multi-layer highlighting (L1 raw text → L4 executive summary)
- Quick Capture - Fast note capture to inbox
- Rich Editor - Tiptap-based editor with highlighting support
- Full-Text Search - Search across all notes and containers
- Keyboard Shortcuts - Fast navigation and note management
| Layer | Technology |
|---|---|
| Backend | FastAPI, SQLAlchemy 2.0 (async), Pydantic v2, Alembic |
| Frontend | Vue 3 (Composition API), Pinia, Vue Router 4, TailwindCSS, Tiptap |
| Database | SQLite (dev), PostgreSQL (prod) |
| Testing | pytest + pytest-asyncio, Vitest |
| Linting | ruff, mypy, bandit |
- Python 3.10+
- Node.js 18+
cd backend
python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/alembic upgrade headcd frontend
npm installcd backend
.venv/bin/uvicorn app.main:app --reloadBackend runs at http://localhost:8000 (API docs at http://localhost:8000/docs)
cd frontend
npm run devFrontend runs at http://localhost:5173
second-brain/
├── backend/
│ ├── app/
│ │ ├── api/v1/ # REST endpoints
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ └── services/ # Business logic
│ ├── tests/
│ └── alembic/ # Migrations
├── frontend/
│ ├── src/
│ │ ├── api/ # API client
│ │ ├── components/ # Vue components
│ │ ├── stores/ # Pinia stores
│ │ ├── views/ # Route pages
│ │ └── types/ # TypeScript types
│ └── package.json
└── README.md
POST /api/v1/notes- Quick capture to inboxGET /api/v1/notes- List with filters (container_id,stage,q)GET /api/v1/notes/{id}- Get single notePUT /api/v1/notes/{id}- Update notePATCH /api/v1/notes/{id}/move- Move to containerPATCH /api/v1/notes/{id}/highlights- Update progressive summarizationDELETE /api/v1/notes/{id}- Delete note
POST /api/v1/containers- Create containerGET /api/v1/containers- List with note countsGET /api/v1/containers/{id}- Get with notesPUT /api/v1/containers/{id}- Update containerPATCH /api/v1/containers/{id}/archive- Archive containerDELETE /api/v1/containers/{id}- Delete container
GET /api/v1/inbox- Uncategorized capturesGET /api/v1/search?q=- Full-text searchGET /api/v1/recent- Recently modified
Configuration via environment variables or .env file:
# Database
DATABASE_URL=sqlite+aiosqlite:///./basb.db # Dev (default)
# DATABASE_URL=postgresql+asyncpg://user:pass@localhost/basb # Prod
# Server
HOST=0.0.0.0
PORT=8000# Backend
cd backend
.venv/bin/pytest # All tests
.venv/bin/pytest -v --cov=app --cov-report=term-missing # With coverage
# Frontend
cd frontend
npm run test
npm run test -- --watch # Watch modecd backend
# Formatting check (apply formatting by removing --check)
.venv/bin/ruff format --check app/ tests/
# Lint
.venv/bin/ruff check app/ tests/
# Type check
.venv/bin/mypy app/
# Security scan
.venv/bin/bandit -r app/ -c pyproject.tomlRun all checks at once:
.venv/bin/pytest && .venv/bin/ruff format --check app/ tests/ && .venv/bin/ruff check app/ tests/ && .venv/bin/mypy app/ && .venv/bin/bandit -r app/ -c pyproject.toml- Input validation on all API boundaries
- Parameterized queries via SQLAlchemy (no raw SQL)
- Pydantic schema validation for all request/response payloads
- CORS configuration for local development
Database Migration Errors:
- Ensure migrations are up to date:
alembic upgrade head - For a fresh start: delete
basb.dband re-run migrations
Frontend API Errors:
- Verify backend is running on port 8000
- Check browser console for CORS issues
Test Failures:
- Ensure you're using the venv: prefix commands with
.venv/bin/(e.g.,.venv/bin/pytest) - Tests use in-memory SQLite, no external deps needed
This is a personal/educational project, but suggestions and feedback are welcome via issues.
MIT License - see LICENSE for details.