# Contributing to Flyer Crawler Thank you for your interest in contributing to Flyer Crawler! This guide will help you understand our development workflow and coding standards. ## Table of Contents - [Getting Started](#getting-started) - [Development Workflow](#development-workflow) - [Code Standards](#code-standards) - [Testing Requirements](#testing-requirements) - [Pull Request Process](#pull-request-process) - [Architecture Decision Records](#architecture-decision-records) - [Working with AI Agents](#working-with-ai-agents) ## Getting Started ### Prerequisites 1. **Windows with Podman Desktop**: See [docs/getting-started/INSTALL.md](docs/getting-started/INSTALL.md) 2. **Node.js 20+**: For running the application 3. **Git**: For version control ### Initial Setup ```bash # Clone the repository git clone cd flyer-crawler.projectium.com # Install dependencies npm install # Start development containers podman start flyer-crawler-postgres flyer-crawler-redis # Start development server npm run dev ``` ## Development Workflow ### Before Making Changes 1. **Read [CLAUDE.md](CLAUDE.md)** - Project guidelines and patterns 2. **Review relevant ADRs** in [docs/adr/](docs/adr/) - Understand architectural decisions 3. **Check existing issues** - Avoid duplicate work 4. **Create a feature branch** - Use descriptive names ```bash git checkout -b feature/descriptive-name # or git checkout -b fix/issue-description ``` ### Making Changes #### Code Changes Follow the established patterns from [docs/development/CODE-PATTERNS.md](docs/development/CODE-PATTERNS.md): 1. **Routes** → **Services** → **Repositories** → **Database** 2. Never access the database directly from routes 3. Use Zod schemas for input validation 4. Follow ADR-034 repository naming conventions: - `get*` - Throws NotFoundError if not found - `find*` - Returns null if not found - `list*` - Returns empty array if none found #### Database Changes When modifying the database schema: 1. Create migration: `sql/migrations/NNNN-description.sql` 2. Update `sql/master_schema_rollup.sql` (complete schema) 3. Update `sql/initial_schema.sql` (identical to rollup) 4. Test with integration tests **CRITICAL**: Schema files must stay synchronized. See [CLAUDE.md#database-schema-sync](CLAUDE.md#database-schema-sync). #### NGINX Configuration Changes When modifying NGINX configurations on the production or test servers: 1. Make changes on the server at `/etc/nginx/sites-available/` 2. Test with `sudo nginx -t` and reload with `sudo systemctl reload nginx` 3. Update the reference copies in the repository root: - `etc-nginx-sites-available-flyer-crawler.projectium.com` - Production - `etc-nginx-sites-available-flyer-crawler-test-projectium-com.txt` - Test 4. Commit the updated reference files These reference files serve as version-controlled documentation of the deployed configurations. ### Testing **IMPORTANT**: All tests must run in the dev container. ```bash # Run all tests podman exec -it flyer-crawler-dev npm test # Run specific test file podman exec -it flyer-crawler-dev npm test -- --run src/path/to/file.test.ts # Type check podman exec -it flyer-crawler-dev npm run type-check ``` #### Before Committing 1. Write tests for new features 2. Update existing tests if behavior changes 3. Run full test suite 4. Run type check 5. Verify documentation is updated See [docs/development/TESTING.md](docs/development/TESTING.md) for detailed testing guidelines. ## Code Standards ### TypeScript - Use strict TypeScript mode - Define types in `src/types/*.ts` files - Avoid `any` - use `unknown` if type is truly unknown - Follow ADR-027 for naming conventions ### Error Handling ```typescript // Repository layer (ADR-001) import { handleDbError, NotFoundError } from '../services/db/errors.db'; try { const result = await client.query(query, values); if (result.rows.length === 0) { throw new NotFoundError('Flyer', id); } return result.rows[0]; } catch (error) { throw handleDbError(error); } ``` ### API Responses ```typescript // Route handlers (ADR-028) import { sendSuccess, sendError } from '../utils/apiResponse'; // Success response return sendSuccess(res, flyer, 'Flyer retrieved successfully'); // Paginated response return sendPaginated(res, { items: flyers, total: count, page: 1, pageSize: 20, }); ``` ### Transactions ```typescript // Multi-operation changes (ADR-002) import { withTransaction } from '../services/db/transaction.db'; await withTransaction(async (client) => { await flyerDb.createFlyer(flyerData, client); await flyerItemDb.createItems(items, client); // Automatically commits on success, rolls back on error }); ``` ## Testing Requirements ### Test Coverage - **Unit tests**: All service functions, utilities, and helpers - **Integration tests**: API endpoints, database operations - **E2E tests**: Critical user flows ### Test Patterns See [docs/subagents/TESTER-GUIDE.md](docs/subagents/TESTER-GUIDE.md) for: - Test helper functions - Mocking patterns - Known testing issues and solutions ### Test Naming ```typescript // Good test names describe('FlyerService.createFlyer', () => { it('should create flyer with valid data', async () => { ... }); it('should throw ValidationError when store_id is missing', async () => { ... }); it('should rollback transaction on item creation failure', async () => { ... }); }); ``` ## Pull Request Process ### 1. Prepare Your PR - [ ] All tests pass in dev container - [ ] Type check passes - [ ] No console.log or debugging code - [ ] Documentation updated (if applicable) - [ ] ADR created (if architectural decision made) ### 2. Create Pull Request **Title Format:** - `feat: Add flyer bulk import endpoint` - `fix: Resolve cache invalidation bug` - `docs: Update testing guide` - `refactor: Simplify transaction handling` **Description Template:** ```markdown ## Summary Brief description of changes ## Changes Made - Added X - Modified Y - Fixed Z ## Related Issues Fixes #123 ## Testing - [ ] Unit tests added/updated - [ ] Integration tests pass - [ ] Manual testing completed ## Documentation - [ ] Code comments added where needed - [ ] ADR created/updated (if applicable) - [ ] User-facing docs updated ``` ### 3. Code Review - Address all reviewer feedback - Keep discussions focused and constructive - Update PR based on feedback ### 4. Merge - Squash commits if requested - Ensure CI passes - Maintainer will merge when approved ## Architecture Decision Records When making significant architectural decisions: 1. Create ADR in `docs/adr/` 2. Use template from existing ADRs 3. Number sequentially 4. Update `docs/adr/index.md` **Examples of ADR-worthy decisions:** - New design patterns - Technology choices - API design changes - Database schema conventions See [docs/adr/index.md](docs/adr/index.md) for existing decisions. ## Working with AI Agents This project uses Claude Code with specialized subagents. See: - [docs/subagents/OVERVIEW.md](docs/subagents/OVERVIEW.md) - Introduction - [CLAUDE.md](CLAUDE.md) - AI agent instructions ### When to Use Subagents | Task | Subagent | | -------------------- | ------------------- | | Writing code | `coder` | | Creating tests | `testwriter` | | Database changes | `db-dev` | | Container/deployment | `devops` | | Security review | `security-engineer` | ### Example ``` Use the coder subagent to implement the bulk flyer import endpoint with proper transaction handling and error responses. ``` ## Git Conventions ### Commit Messages Follow conventional commits: ``` feat: Add watchlist price alerts fix: Resolve duplicate flyer upload bug docs: Update deployment guide refactor: Simplify auth middleware test: Add integration tests for flyer API ``` ### Branch Naming ``` feature/watchlist-alerts fix/duplicate-upload-bug docs/update-deployment-guide refactor/auth-middleware ``` ## Getting Help - **Documentation**: Start with [docs/README.md](docs/README.md) - **Testing Issues**: See [docs/development/TESTING.md](docs/development/TESTING.md) - **Architecture Questions**: Review [docs/adr/index.md](docs/adr/index.md) - **Debugging**: Check [docs/development/DEBUGGING.md](docs/development/DEBUGGING.md) - **AI Agents**: Consult [docs/subagents/OVERVIEW.md](docs/subagents/OVERVIEW.md) ## Code of Conduct - Be respectful and inclusive - Welcome newcomers - Focus on constructive feedback - Assume good intentions ## License By contributing, you agree that your contributions will be licensed under the same license as the project. --- Thank you for contributing to Flyer Crawler! 🎉