349 lines
8.6 KiB
Markdown
349 lines
8.6 KiB
Markdown
# 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 <repository-url>
|
|
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! 🎉
|