|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Repository Structure |
| 6 | + |
| 7 | +Imbi is a DevOps Service Management Platform with a multi-repository architecture using Git submodules: |
| 8 | + |
| 9 | +- **api/** - Python backend (Tornado/sprockets-postgres) - submodule from imbi-api |
| 10 | +- **ui/** - React frontend (webpack, Tailwind CSS) - submodule from imbi-ui |
| 11 | +- **ddl/** - PostgreSQL database schema (pgTAP tests) - submodule from imbi-schema |
| 12 | +- **openapi/** - OpenAPI specification - submodule from imbi-openapi |
| 13 | + |
| 14 | +**CRITICAL**: Always run `git submodule update --init --recursive` after cloning or when submodules are missing. |
| 15 | + |
| 16 | +## Development Setup |
| 17 | + |
| 18 | +### Initial Setup |
| 19 | +```bash |
| 20 | +# Initialize all submodules |
| 21 | +git submodule update --init --recursive |
| 22 | + |
| 23 | +# Setup the entire project (api, openapi, ui) |
| 24 | +make setup |
| 25 | + |
| 26 | +# Or setup individual components |
| 27 | +cd api && make setup # Creates Python venv, installs deps, runs bootstrap |
| 28 | +cd ui && yarn install |
| 29 | +cd openapi && yarn install |
| 30 | +``` |
| 31 | + |
| 32 | +### Running Locally |
| 33 | +```bash |
| 34 | +# Terminal 1: Start UI dev server (webpack-dev-server with hot reload) |
| 35 | +cd ui |
| 36 | +yarn serve # Runs on http://localhost:8080 |
| 37 | + |
| 38 | +# Terminal 2: Start API server |
| 39 | +cd api |
| 40 | +source env/bin/activate |
| 41 | +imbi --debug build/debug.yaml # Runs on http://localhost:8000 |
| 42 | +``` |
| 43 | + |
| 44 | +Default credentials: username `test`, password `password` |
| 45 | + |
| 46 | +### Docker Development Environment |
| 47 | + |
| 48 | +The `api/bootstrap` script initializes Docker Compose services and generates configuration: |
| 49 | +- **postgres** - PostgreSQL with Imbi schema (aweber/imbi-postgres:latest) |
| 50 | +- **ldap** - OpenLDAP for authentication |
| 51 | +- **opensearch** - Search backend |
| 52 | +- **redis** - Session and stats storage |
| 53 | + |
| 54 | +Running `api/bootstrap` creates: |
| 55 | +- `api/.env` - Environment variables for service ports |
| 56 | +- `api/build/debug.yaml` - Development configuration |
| 57 | +- `api/build/test.yaml` - Test configuration |
| 58 | + |
| 59 | +## Common Development Commands |
| 60 | + |
| 61 | +### Python API (from api/) |
| 62 | +```bash |
| 63 | +# Run all tests (lint + coverage) |
| 64 | +make test |
| 65 | + |
| 66 | +# Run linting only (pre-commit hooks: bandit, flake8, yapf) |
| 67 | +make lint |
| 68 | + |
| 69 | +# Run tests with coverage |
| 70 | +make coverage |
| 71 | + |
| 72 | +# Run a single test file |
| 73 | +source env/bin/activate |
| 74 | +python -m unittest tests.test_user |
| 75 | + |
| 76 | +# Run a specific test |
| 77 | +python -m unittest tests.test_user.TestClass.test_method |
| 78 | + |
| 79 | +# Apply code formatting |
| 80 | +env/bin/pre-commit run yapf --all-files |
| 81 | + |
| 82 | +# Check security issues |
| 83 | +env/bin/pre-commit run bandit --all-files |
| 84 | +``` |
| 85 | + |
| 86 | +### UI (from ui/) |
| 87 | +```bash |
| 88 | +# Run all UI tests (eslint, prettier, depcheck, jest) |
| 89 | +yarn test |
| 90 | + |
| 91 | +# Run linting only |
| 92 | +yarn eslint |
| 93 | + |
| 94 | +# Format code |
| 95 | +yarn prettier |
| 96 | + |
| 97 | +# Check formatting without changes |
| 98 | +yarn prettier-check |
| 99 | + |
| 100 | +# Build production bundle |
| 101 | +NODE_ENV=production yarn build |
| 102 | +``` |
| 103 | + |
| 104 | +### Database (from ddl/) |
| 105 | +```bash |
| 106 | +# Run DDL tests (pgTAP) |
| 107 | +make test |
| 108 | + |
| 109 | +# Bootstrap DDL environment |
| 110 | +make bootstrap |
| 111 | +``` |
| 112 | + |
| 113 | +### Full Distribution Build (from root) |
| 114 | +```bash |
| 115 | +# Builds OpenAPI docs, UI bundle, and Python package |
| 116 | +make dist |
| 117 | +``` |
| 118 | + |
| 119 | +## Architecture Overview |
| 120 | + |
| 121 | +### Backend (Python/Tornado) |
| 122 | + |
| 123 | +**Core Framework:** |
| 124 | +- Tornado async web framework |
| 125 | +- sprockets-postgres for async PostgreSQL connections with connection pooling |
| 126 | +- sprockets.http for application scaffolding |
| 127 | +- tornado-openapi3 for API validation |
| 128 | + |
| 129 | +**Authentication:** |
| 130 | +- Multi-provider: LDAP (ldap3), Google OAuth2, local users |
| 131 | +- Session management via Redis (aioredis) |
| 132 | +- Permission-based access control defined in `permissions.py` |
| 133 | + |
| 134 | +**Endpoint Pattern:** |
| 135 | +All endpoints inherit from base classes in `api/imbi/endpoints/base.py`: |
| 136 | +- `CRUDRequestHandler` - Full CRUD operations |
| 137 | +- `CollectionRequestHandler` - List/Create operations |
| 138 | +- `RecordRequestHandler` - Get/Update/Delete single records |
| 139 | + |
| 140 | +Endpoints define SQL queries as class attributes: |
| 141 | +- `GET_SQL` - Fetch single record |
| 142 | +- `COLLECTION_SQL` - Fetch collection (supports {{WHERE}} and {{ORDER_BY}} placeholders) |
| 143 | +- `POST_SQL`, `PATCH_SQL`, `DELETE_SQL` - Mutation operations |
| 144 | +- `FIELDS` - List of allowed fields for the endpoint |
| 145 | +- `TTL` - Cache timeout |
| 146 | + |
| 147 | +**Search:** |
| 148 | +OpenSearch integration for project and operations log search (`api/imbi/opensearch/`) |
| 149 | + |
| 150 | +**Automations:** |
| 151 | +External integrations in `api/imbi/automations/`: |
| 152 | +- GitHub, GitLab, Sentry, SonarQube, PagerDuty |
| 153 | +- Triggered by project lifecycle events |
| 154 | + |
| 155 | +### Frontend (React) |
| 156 | + |
| 157 | +**Structure:** |
| 158 | +- `ui/src/js/views/` - Page components organized by feature |
| 159 | +- `ui/src/js/components/` - Reusable React components |
| 160 | +- `ui/src/js/schema/` - JSON schemas for forms and validation |
| 161 | +- `ui/src/js/state.jsx` - Global state management (React Context) |
| 162 | + |
| 163 | +**Styling:** |
| 164 | +- Tailwind CSS for utility classes |
| 165 | +- Custom theme in `ui/src/js/theme.js` |
| 166 | +- FontAwesome icons via `@fortawesome/react-fontawesome` |
| 167 | + |
| 168 | +**Build:** |
| 169 | +- Webpack for bundling (configs: webpack.dev.js, webpack.production.js) |
| 170 | +- Babel for JSX/ES6+ transpilation |
| 171 | +- Hot module replacement in dev mode |
| 172 | + |
| 173 | +### Database |
| 174 | + |
| 175 | +**Schema Management:** |
| 176 | +- All schema in `ddl/` with MANIFEST file defining load order |
| 177 | +- Versioned in `v1` schema |
| 178 | +- pgTAP tests in `ddl/tests/` |
| 179 | +- Database functions for computed values (e.g., `v1.project_score()`) |
| 180 | + |
| 181 | +**Key Concepts:** |
| 182 | +- Projects are the central entity (namespaced, typed, scored) |
| 183 | +- Facts: typed key-value metadata for projects |
| 184 | +- Components: Software inventory (SBOM) tracking |
| 185 | +- Operations Log: Deployment and incident history |
| 186 | +- Integrations: OAuth2 connections to external services |
| 187 | + |
| 188 | +## Configuration |
| 189 | + |
| 190 | +Configuration is YAML-based (see `example.yaml`): |
| 191 | +- `http` - Server settings (port, processes, xheaders) |
| 192 | +- `postgres` - Database connection (URL, pool settings, timeouts) |
| 193 | +- `ldap` - LDAP authentication settings |
| 194 | +- `session` - Redis session configuration |
| 195 | +- `stats` - Redis stats configuration |
| 196 | +- `opensearch` - Search backend settings |
| 197 | +- `logging` - Python dictConfig format |
| 198 | + |
| 199 | +## Testing Strategy |
| 200 | + |
| 201 | +**Python:** |
| 202 | +- Unit tests in `api/tests/` mirroring `api/imbi/` structure |
| 203 | +- Tests use unittest framework |
| 204 | +- Coverage target tracked via coverage.py |
| 205 | +- Security scanning with bandit |
| 206 | +- Style enforcement via flake8 + yapf |
| 207 | + |
| 208 | +**JavaScript:** |
| 209 | +- Jest for unit tests |
| 210 | +- ESLint for linting (react, react-hooks plugins) |
| 211 | +- Prettier for formatting |
| 212 | +- Husky pre-commit hooks for automated checks |
| 213 | + |
| 214 | +**Database:** |
| 215 | +- pgTAP for DDL testing |
| 216 | +- plpgsql_check for function validation |
| 217 | + |
| 218 | +## Code Style |
| 219 | + |
| 220 | +**Python:** |
| 221 | +- Strict PEP-8 compliance |
| 222 | +- Import order: pycharm style (stdlib, third-party, local) |
| 223 | +- YAPF formatting with specific config in setup.cfg |
| 224 | +- Docstrings for public modules/classes (RST format) |
| 225 | + |
| 226 | +**JavaScript:** |
| 227 | +- Prettier with default config |
| 228 | +- ESLint rules for React best practices |
| 229 | +- Functional components with hooks preferred |
| 230 | + |
| 231 | +## Release Process |
| 232 | + |
| 233 | +1. Update VERSION file in `api/` |
| 234 | +2. Update submodules: `git submodule update --remote --merge` |
| 235 | +3. Commit: `git commit -m 'Release version X.Y.Z' -a` |
| 236 | +4. Tag: `git tag X.Y.Z && git push origin X.Y.Z` |
| 237 | +5. GitHub Actions handles: UI build → Python package → PyPI → Docker Hub |
| 238 | + |
| 239 | +## Important Notes |
| 240 | + |
| 241 | +- **Submodules**: The main repo is primarily a coordination point; most code lives in submodules |
| 242 | +- **Database First**: Schema changes in ddl/ must be tagged before API changes |
| 243 | +- **OpenAPI**: Spec is built from openapi/ and bundled into the API at build time |
| 244 | +- **Session Management**: Redis-backed sessions with configurable TTL |
| 245 | +- **CORS**: Configurable CORS support for cross-origin API access |
| 246 | +- **Stats**: Real-time metrics via Redis and periodic aggregation |
0 commit comments