docs: add CONTRIBUTING.md with operational guidelines
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
192
CONTRIBUTING.md
Normal file
192
CONTRIBUTING.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
# Contributing to MosaicIQ
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
MosaicIQ/
|
||||||
|
├── MosaicIQ/ # Main application
|
||||||
|
│ ├── src/ # React + TypeScript frontend
|
||||||
|
│ │ ├── components/ # UI components (Home, Research, Terminal, etc.)
|
||||||
|
│ │ ├── hooks/ # React hooks
|
||||||
|
│ │ ├── lib/ # Shared utilities
|
||||||
|
│ │ ├── news/ # News feed frontend module
|
||||||
|
│ │ ├── research/ # Research workspace frontend module
|
||||||
|
│ │ ├── shared/ # Shared types and helpers
|
||||||
|
│ │ └── types/ # TypeScript type definitions
|
||||||
|
│ ├── src-tauri/ # Rust backend (Tauri 2)
|
||||||
|
│ │ ├── src/
|
||||||
|
│ │ │ ├── agent/ # AI agent integration (rig-core)
|
||||||
|
│ │ │ ├── commands/ # Tauri command handlers (thin bridge layer)
|
||||||
|
│ │ │ ├── mappings/ # XBRL concept mapping logic
|
||||||
|
│ │ │ ├── news/ # News feed ingestion and storage
|
||||||
|
│ │ │ ├── portfolio/ # Portfolio and quote data
|
||||||
|
│ │ │ ├── research/ # Research workspaces, notes, models
|
||||||
|
│ │ │ ├── terminal/ # Terminal command parsing and routing
|
||||||
|
│ │ │ ├── error.rs # Unified error types
|
||||||
|
│ │ │ ├── state.rs # Shared application state
|
||||||
|
│ │ │ └── lib.rs # Tauri app entry point
|
||||||
|
│ │ └── tests/ # Rust integration tests
|
||||||
|
│ ├── docs/ # Project documentation
|
||||||
|
│ └── public/ # Static assets
|
||||||
|
├── agent.md # Agent code standards (Rust/backend focus)
|
||||||
|
└── CONTRIBUTING.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
| Layer | Technology |
|
||||||
|
|---------------|-------------------------------------------------------------------|
|
||||||
|
| Desktop shell | Tauri 2 |
|
||||||
|
| Frontend | React 19, TypeScript 5.8, Vite 7, TailwindCSS 4 |
|
||||||
|
| State | Zustand (client), TanStack Query (server cache) |
|
||||||
|
| Rich text | TipTap |
|
||||||
|
| Charts | Recharts |
|
||||||
|
| Spreadsheets | UniverJS |
|
||||||
|
| Backend | Rust (edition 2021) |
|
||||||
|
| Database | SQLite via rusqlite (bundled) |
|
||||||
|
| HTTP | reqwest |
|
||||||
|
| Data sources | Yahoo Finance (yfinance-rs), RSS/Atom feeds, SEC EDGAR |
|
||||||
|
| AI/Agent | rig-core |
|
||||||
|
| Package mgr | bun (frontend), Cargo (backend) |
|
||||||
|
| Node version | 24.14.1 (see `.nvmrc`) |
|
||||||
|
|
||||||
|
## Branch Naming
|
||||||
|
|
||||||
|
| Pattern | Purpose |
|
||||||
|
|--------------------------------|----------------------------------|
|
||||||
|
| `main` | Production-ready code |
|
||||||
|
| `mvp-X.Y.Z` | Release/milestone branches |
|
||||||
|
| `<handle>/<short-description>` | Feature branches |
|
||||||
|
| `fix/<short-description>` | Bug fix branches |
|
||||||
|
| `refactor/<short-description>` | Refactoring branches |
|
||||||
|
|
||||||
|
Examples: `t3code/expand-inspector-editor`, `fix/news-feed-stale-cache`
|
||||||
|
|
||||||
|
## Commit Conventions
|
||||||
|
|
||||||
|
Use [Conventional Commits](https://www.conventionalcommits.org/) with a short subject line (max 72 chars):
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <description>
|
||||||
|
|
||||||
|
[optional body]
|
||||||
|
[optional footer(s)]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Types
|
||||||
|
|
||||||
|
| Type | When to use |
|
||||||
|
|------------|------------------------------------------------|
|
||||||
|
| `feat` | New feature or user-facing capability |
|
||||||
|
| `fix` | Bug fix |
|
||||||
|
| `refactor` | Code restructuring without behavior change |
|
||||||
|
| `docs` | Documentation only |
|
||||||
|
| `test` | Adding or updating tests |
|
||||||
|
| `chore` | Build, tooling, dependencies, CI |
|
||||||
|
| `perf` | Performance improvement |
|
||||||
|
| `style` | Formatting, whitespace (no logic change) |
|
||||||
|
|
||||||
|
### Scopes
|
||||||
|
|
||||||
|
Use the module or area the change touches:
|
||||||
|
|
||||||
|
- `terminal` — terminal command parsing/routing
|
||||||
|
- `news` — news feed ingestion, storage, UI
|
||||||
|
- `research` — workspaces, notes, models
|
||||||
|
- `portfolio` — portfolio and quote data
|
||||||
|
- `mappings` — XBRL concept mappings
|
||||||
|
- `agent` — AI agent integration
|
||||||
|
- `ui` — frontend UI components
|
||||||
|
- `state` — app state management
|
||||||
|
- `db` — SQLite schema or migration changes
|
||||||
|
- `build` — build system, Cargo, Vite config
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```
|
||||||
|
feat(news): add keyword filtering to news feed query
|
||||||
|
fix(terminal): handle empty ticker in lookup command
|
||||||
|
refactor(research): decompose workspace controller into separate hooks
|
||||||
|
docs: add CONTRIBUTING.md with operational guidelines
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull Request Flow
|
||||||
|
|
||||||
|
1. Create a feature branch from `main` (or the relevant release branch).
|
||||||
|
2. Make changes in logical commits following the conventions above.
|
||||||
|
3. Ensure the project compiles and tests pass before requesting review:
|
||||||
|
- Frontend: `bun install && bun run build`
|
||||||
|
- Backend: `cd MosaicIQ/src-tauri && cargo check && cargo test`
|
||||||
|
4. Open a PR against the target branch with a clear description of what changed and why.
|
||||||
|
5. At least one approval required before merge.
|
||||||
|
6. Squash-merge is preferred for feature branches to keep history clean.
|
||||||
|
|
||||||
|
## Code Review Expectations
|
||||||
|
|
||||||
|
- **No dead code** in the active codepath. Remove unused modules, imports, and variables.
|
||||||
|
- **No `unwrap()` or `expect()`** in production Rust code. Use proper error propagation.
|
||||||
|
- **No mock or placeholder logic** in production paths.
|
||||||
|
- **No new public API** without documentation (doc comments for Rust, JSDoc for TypeScript).
|
||||||
|
- **No new stateful logic** without at least focused unit test coverage.
|
||||||
|
- **No structural change** without verifying `cargo check` and `bun run build` both pass.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Rust (Backend)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd MosaicIQ/src-tauri
|
||||||
|
cargo test # All tests
|
||||||
|
cargo test --lib # Unit tests only
|
||||||
|
cargo test --test <name> # Specific integration test
|
||||||
|
```
|
||||||
|
|
||||||
|
- Every backend behavior change must add or update tests.
|
||||||
|
- Use `test_support.rs` for shared test fixtures.
|
||||||
|
- Use `wiremock` for HTTP mocking, `tempfile` for filesystem isolation.
|
||||||
|
|
||||||
|
### TypeScript (Frontend)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd MosaicIQ
|
||||||
|
bun test
|
||||||
|
```
|
||||||
|
|
||||||
|
- Write tests for hooks, utilities, and data transformations.
|
||||||
|
- Component tests should cover user-facing behavior, not implementation details.
|
||||||
|
|
||||||
|
## Secrets and Security
|
||||||
|
|
||||||
|
- Never commit secrets, API keys, credentials, or tokens to the repository.
|
||||||
|
- API keys (e.g., for remote AI providers) are stored at runtime via the Tauri store plugin, not in code.
|
||||||
|
- Validate all external inputs (API responses, user input, file uploads) before processing.
|
||||||
|
- Sanitize data before storage or display.
|
||||||
|
- Report security concerns to the CTO immediately before merging.
|
||||||
|
|
||||||
|
## Architecture Principles
|
||||||
|
|
||||||
|
These principles guide all technical decisions in this project:
|
||||||
|
|
||||||
|
1. **Data freshness vs cost** — Free sources have rate limits. Cache aggressively with clear timestamps. Prefer stale data with indicators over paid real-time feeds.
|
||||||
|
2. **Separation of concerns** — Data ingestion, processing, storage, and presentation layers must be independently testable and replaceable.
|
||||||
|
3. **API design as product** — The terminal is API-first. Internal and external interfaces should be clean, documented, and versioned.
|
||||||
|
4. **Fail gracefully** — If a data source is down, show available data with a clear indicator of what is missing. Never crash on external failures.
|
||||||
|
5. **Idempotency** — Data ingestion and processing pipelines must be safe to rerun without duplicating data or side effects.
|
||||||
|
6. **Progressive complexity** — Start with the simplest architecture that solves the problem. Add complexity only when the simple version is proven insufficient.
|
||||||
|
7. **Observability first** — Log ingestion events, API calls, errors, and data quality metrics from day one.
|
||||||
|
|
||||||
|
## Backend Patterns (Rust/Tauri)
|
||||||
|
|
||||||
|
- Keep Tauri command handlers thin. Business logic belongs in service modules, not command handlers.
|
||||||
|
- Return typed errors from services. Convert to Tauri-compatible errors only at the command boundary.
|
||||||
|
- Keep shared mutable state behind a narrow API. Command handlers must not reach into internal maps directly.
|
||||||
|
- Use conventional Rust module layout (`mod.rs` or flat sibling modules).
|
||||||
|
- Prefer small, composable functions over procedural blocks.
|
||||||
|
|
||||||
|
## Frontend Patterns (React/TypeScript)
|
||||||
|
|
||||||
|
- Use Zustand for global client state. Use TanStack Query for server-derived state.
|
||||||
|
- Components in `src/components/` follow the existing decomposition pattern (screen/workbench/rail).
|
||||||
|
- Custom hooks in `src/hooks/` encapsulate data fetching and state logic.
|
||||||
|
- Shared types in `src/types/`. Do not scatter type definitions across component files.
|
||||||
|
- Use TailwindCSS utility classes. Follow the existing design system conventions.
|
||||||
Reference in New Issue
Block a user