Revise contributing guidelines for clarity and detail

Updated contributing guidelines to clarify architectural constraints and development setup instructions.
This commit is contained in:
ulsklyc
2026-03-29 15:43:49 +02:00
committed by GitHub
parent a4cc520342
commit 29c9292d2d
+183 -33
View File
@@ -1,36 +1,173 @@
# Contributing to Oikos # Contributing to Oikos
Thanks for your interest in contributing. Oikos is a small, opinionated project — this guide covers the constraints and conventions you need to know before submitting code. Thanks for your interest in contributing. Oikos is a small, opinionated project with deliberate architectural constraints. This guide covers what you need to know before submitting code.
## Ground Rules ---
**Oikos has a hard "no frameworks, no build tools" constraint.** This is not a temporary limitation — it's an architectural decision. Specifically: ## Hard Constraints
- No React, Vue, Svelte, Angular, or any frontend framework **Oikos enforces a strict "no frameworks, no build tools" policy.** This is a permanent architectural decision, not a temporary limitation.
- No Webpack, Vite, Rollup, esbuild, or any bundler
- No TypeScript (plain JavaScript with ES modules)
- No CSS libraries (Tailwind, Bootstrap, etc.)
- No external frontend dependencies except Lucide Icons (self-hosted SVG sprite)
If your contribution requires adding a frontend dependency, it will not be merged. Backend dependencies are evaluated case-by-case but should remain minimal. Specifically — the following will **not** be merged:
## Getting Started - Frontend frameworks (React, Vue, Svelte, Angular, etc.)
- Bundlers or transpilers (Webpack, Vite, Rollup, esbuild, TypeScript, etc.)
- CSS libraries (Tailwind, Bootstrap, etc.)
- External frontend dependencies of any kind (except Lucide Icons as self-hosted SVG sprite)
Backend dependencies are evaluated case-by-case but must remain minimal. When in doubt, open an issue before writing code.
---
## Development Setup
### Prerequisites
- Node.js ≥ 22 (required for `--experimental-sqlite` in tests)
- Git
### Getting started
```bash ```bash
git clone https://github.com/ulsklyc/oikos.git git clone https://github.com/ulsklyc/oikos.git
cd oikos cd oikos
npm install npm install
cp .env.example .env cp .env.example .env
# Set SESSION_SECRET — skip DB_ENCRYPTION_KEY for local dev # Set SESSION_SECRET — leave DB_ENCRYPTION_KEY empty (no SQLCipher needed locally)
npm run dev npm run dev
``` ```
Run tests before submitting: `npm run dev` starts the server with `--watch` for automatic restarts on file changes.
### Running tests
```bash ```bash
npm test # Requires Node >=22 (uses --experimental-sqlite) npm test # All suites
``` ```
Tests use the Node.js built-in test runner with in-memory SQLite. No running server or database required — tests import route handlers directly.
---
## Project Structure
Understanding where things live helps you find the right place for your changes:
```
server/
index.js # Express entry point, middleware chain
db.js # SQLite connection + migration runner (append-only)
auth.js # Session auth + user management
routes/ # API route handlers — one file per module
services/ # Business logic (calendar sync, recurrence engine)
public/
index.html # SPA shell (single entry point)
router.js # Client-side History API router
api.js # Fetch wrapper (auth, CSRF, error handling)
styles/
tokens.css # Design tokens — all colors, radii, shadows, fonts
components/ # Reusable Web Components (oikos-* prefix)
pages/ # Page modules — each exports a render() function
sw.js # Service worker
tests/ # One test file per module
docs/ # Product spec, screenshots
```
**Key patterns:**
- Every API route lives in `server/routes/` and follows the same `try/catch` → JSON response pattern
- Every frontend page is an ES module in `public/pages/` that exports `render()`
- All design values come from `tokens.css` — never hardcode colors, radii, or shadows
- Database migrations are appended to the `migrations` array in `server/db.js` — never modify existing entries
---
## Workflow
### 1. Find or create an issue
Before starting work, check the [existing issues](https://github.com/ulsklyc/oikos/issues). For anything beyond a trivial fix, open an issue first to discuss the approach. This avoids wasted effort on changes that conflict with the project's direction.
### 2. Fork and branch
```bash
# Fork on GitHub, then:
git clone https://github.com/YOUR-USERNAME/oikos.git
cd oikos
git remote add upstream https://github.com/ulsklyc/oikos.git
git checkout -b feat/your-feature-name
```
**Branch naming:**
| Prefix | Use for | Example |
|--------|---------|---------|
| `feat/` | New features | `feat/csv-import-budget` |
| `fix/` | Bug fixes | `fix/calendar-sync-timezone` |
| `refactor/` | Internal changes (no behavior change) | `refactor/extract-date-utils` |
| `docs/` | Documentation only | `docs/improve-setup-guide` |
| `chore/` | Maintenance, CI, dependencies | `chore/update-helmet` |
### 3. Keep your fork in sync
```bash
git fetch upstream
git rebase upstream/main
```
Rebase before opening a PR. Merge commits will be squashed.
### 4. Commit
Follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):
```
<type>(<scope>): <description>
[optional body]
[optional footer]
```
**Types:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `style` (formatting, not CSS)
**Scope:** The module or area affected — `tasks`, `shopping`, `meals`, `calendar`, `budget`, `notes`, `contacts`, `auth`, `db`, `ui`, `pwa`
**Examples:**
```
feat(meals): add drag & drop between day slots
fix(calendar): handle timezone offset in recurring events
docs(readme): add Apple CalDAV setup instructions
refactor(auth): extract session validation into middleware
test(budget): add CSV export edge cases
chore: update express to 4.21
```
**Rules:**
- Subject line: imperative mood, lowercase, no period, max 72 characters
- Body (optional): explain *why*, not *what* — the diff shows the what
- One logical change per commit — don't mix features with formatting
### 5. Open a pull request
- Target branch: `main`
- Title: follows the same Conventional Commits format as your commits
- Description: explain what the PR does, why, and link the related issue (`Closes #123`)
- Keep PRs focused — one feature or fix per PR
**Before opening:**
```bash
npm test # All tests pass
```
### 6. Review and merge
PRs are reviewed by the maintainer. Expect feedback within a few days. Once approved, PRs are squash-merged into `main`.
---
## Code Conventions ## Code Conventions
### General ### General
@@ -46,46 +183,59 @@ npm test # Requires Node >=22 (uses --experimental-sqlite)
- Web Component prefix: `oikos-` (one component per file) - Web Component prefix: `oikos-` (one component per file)
- All UI text in **German** (the app targets German-speaking families) - All UI text in **German** (the app targets German-speaking families)
- Date format: `DD.MM.YYYY` — Time format: `HH:MM` (24h) - Date format: `DD.MM.YYYY` — Time format: `HH:MM` (24h)
- Pages are ES modules in `public/pages/` that export a `render()` function - CSS uses design tokens from `public/styles/tokens.css` — never hardcode values
- CSS uses design tokens from `public/styles/tokens.css` — don't hardcode colors or radii - Pages export a `render()` function, no side effects on import
### Backend ### Backend
- API routes live in `server/routes/`, one file per module - One route file per module in `server/routes/`
- API responses: `{ data: ... }` on success, `{ error: string, code: number }` on failure - API responses: `{ data: ... }` on success, `{ error: string, code: number }` on failure
- Database migrations go in the `migrations` array in `server/db.js`**append only, never modify existing entries** - Database migrations: append to the `migrations` array in `server/db.js`**never modify existing entries**
- Every table: `id INTEGER PRIMARY KEY`, `created_at TEXT`, `updated_at TEXT` - Every table: `id INTEGER PRIMARY KEY`, `created_at TEXT`, `updated_at TEXT` (ISO 8601)
### Testing ### Testing
- Tests use the Node.js built-in test runner with in-memory SQLite (`--experimental-sqlite`)
- One test file per module in `tests/` - One test file per module in `tests/`
- No running server needed — tests import route handlers directly - Tests use in-memory SQLite via `--experimental-sqlite`
- Import route handlers directly — no HTTP calls, no running server
## Submitting Changes ---
1. Fork the repo and create a branch from `main` ## Changelog
2. Make your changes following the conventions above
3. Add or update tests if applicable
4. Run `npm test` and make sure all tests pass
5. Open a pull request with a clear description of what and why
Keep PRs focused. One feature or fix per PR. Large refactors should be discussed in an issue first. User-facing changes should be reflected in [`CHANGELOG.md`](CHANGELOG.md). If your PR adds a feature, fixes a bug, or changes behavior, add an entry under `[Unreleased]` in the appropriate category (`Added`, `Changed`, `Fixed`, `Removed`, `Security`).
## Reporting Bugs Format: imperative mood, one line per change, user-oriented language.
```markdown
### Added
- Add CSV import for budget entries
```
---
## Reporting Issues
### Bugs
[Open an issue](https://github.com/ulsklyc/oikos/issues/new) with: [Open an issue](https://github.com/ulsklyc/oikos/issues/new) with:
- What you expected to happen - What you expected vs. what happened
- What actually happened
- Steps to reproduce - Steps to reproduce
- Environment (browser, OS, Docker version if relevant) - Environment (browser, OS, Docker version if relevant)
- Screenshots if applicable
## Feature Requests ### Feature requests
[Open an issue](https://github.com/ulsklyc/oikos/issues/new) describing the use case. Explain the problem before proposing a solution — there might be a simpler approach that fits the existing architecture. Describe the **use case** before proposing a solution. There might be a simpler approach that fits the existing architecture.
Features that conflict with the project's constraints (see above) or significantly expand scope will likely be declined. When in doubt, ask first. Features that conflict with the project's [hard constraints](#hard-constraints) or significantly expand scope will likely be declined. When in doubt, ask first.
### Security vulnerabilities
Do **not** open a public issue. See [`SECURITY.md`](SECURITY.md) for responsible disclosure.
---
## License ## License