Skip to the content.

Development Guide

Guide for developers working on the Open Receipt OCR codebase.

Project Structure

open-receipt-ocr/
├── client/                      # Angular frontend
│   ├── src/
│   │   ├── app/
│   │   │   ├── components/      # Reusable UI components
│   │   │   ├── layouts/         # Page layouts
│   │   │   ├── pipes/           # Custom pipes & parsers
│   │   │   └── services/        # API & utility services
│   │   └── assets/
│   └── public/                  # Static assets & translations
├── server/                      # NestJS backend
│   ├── src/
│   │   ├── core/                # Core modules
│   │   │   ├── database/        # TypeORM & database
│   │   │   ├── storage/         # Storage providers
│   │   │   ├── secrets/         # Secret management
│   │   │   └── types/           # Shared type definitions
│   │   ├── ocr-jobs/            # OCR job management
│   │   ├── worker/              # Background job processing
│   │   │   ├── ocr/             # OCR processor implementations
│   │   │   └── config/
│   │   └── main.ts              # Server entry point
│   ├── .env.example             # Environment variables template
│   └── worker.ts                # Worker process entry point
├── packages/
│   ├── types/                   # Shared TypeScript types
│   │   └── src/
│   │       ├── ocr-provider.enum.ts      # OCR provider enum
│   │       └── ...
│   └── ...
├── docker-compose.yaml          # Multi-container setup
├── Dockerfile                   # Docker image
└── package.json                 # Root package (monorepo)

Development Setup

Prerequisites

Initial Setup

# Clone repository
git clone https://github.com/iursevla/open-receipt-ocr.git
cd open-receipt-ocr

# Install dependencies
npm install

# Setup environment
cp server/.env.example server/.env
# Edit server/.env with your configuration

# Start Redis
redis-server  # or: docker run -d -p 6379:6379 redis:latest

# Start development server
npm run dev

Running Individual Services

# Start backend only
npm run dev:server

# Start frontend only (in another terminal)
npm run dev:client

# Start worker only (in another terminal)
npm run dev:worker

Technology Stack

Frontend

Backend

DevOps

Code Standards

TypeScript

Example:

interface OcrResult {
  markdown: string;
  rawText: string;
}

/**
 * Process a file with the specified OCR provider
 */
async function processFile(file: File, provider: OcrProvider): Promise<OcrResult> {
  // implementation
}

File Naming

Angular Components

import { Component } from '@angular/core';

@Component({
  selector: 'app-receipt-viewer',
  templateUrl: './receipt-viewer.component.html',
  styleUrls: ['./receipt-viewer.component.scss']
})
export class ReceiptViewerComponent {
  // Component logic
}

NestJS Services

import { Injectable } from '@nestjs/common';

@Injectable()
export class OcrJobService {
  constructor(private repository: OcrJobRepository) {}

  async process(jobId: number): Promise<void> {
    // Business logic
  }
}

Adding Features

Add a New OCR Provider

See Extending Guide for detailed instructions.

Add a New API Endpoint

  1. Create a new controller or add to existing:
// server/src/ocr-jobs/ocr-jobs.controller.ts
@Controller('ocr-jobs')
export class OcrJobsController {
  constructor(private service: OcrJobService) {}

  @Get(':id')
  async getJob(@Param('id') id: number) {
    return this.service.findOne(id);
  }
}
  1. Add corresponding service method
  2. Add tests for the endpoint
  3. Update API documentation

Add a New Angular Component

  1. Generate using Angular CLI:
ng generate component components/receipt-upload --skip-tests
  1. Add to appropriate module’s declarations
  2. Style with SCSS
  3. Add unit tests

Testing

Run All Tests

npm run test

Run Specific Test

npm run test -- --include='**/ocr.processor.spec.ts'

Test Coverage

npm run test:cov

Coverage reports are generated in the coverage/ directory.

Writing Tests

Backend example (NestJS):

describe('OcrJobService', () => {
  let service: OcrJobService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [OcrJobService],
    }).compile();

    service = module.get<OcrJobService>(OcrJobService);
  });

  it('should process a job', async () => {
    const result = await service.processJob(1);
    expect(result).toBeDefined();
  });
});

Git Workflow

Branch Naming

Example: feature/add-paddle-ocr-support

Commit Messages

Use conventional commits:

type(scope): description

[optional body]
[optional footer]

Types: feat, fix, docs, style, refactor, test, chore

Example:

feat(ocr): add support for local PaddleOCR

- Integrate paddleocr npm package
- Add configuration option PADDLE_OCR_LOCAL_ENABLED
- Implement PaddleOCR processor

Closes #42

Pull Request Checklist

Debugging

Backend

Enable debug logging:

DEBUG=open-receipt-ocr:*

Use VS Code debugger with server/.vscode/launch.json:

{
  "type": "node",
  "request": "launch",
  "name": "NestJS Server",
  "program": "${workspaceFolder}/server/dist/main.js",
  "cwd": "${workspaceFolder}/server"
}

Frontend

Use Angular DevTools Chrome extension or:

// In component
constructor(private logger: Logger) {}

ngOnInit() {
  this.logger.log('Component initialized', this.data);
}

Database

Query SQLite directly:

sqlite3 data/db/ocr.sqlite
sqlite> .tables
sqlite> SELECT * FROM ocr_jobs LIMIT 5;

Redis

Monitor Redis commands:

redis-cli
127.0.0.1:6379> MONITOR

Building for Production

Build Docker Image

docker build -t open-receipt-ocr:latest .

Build Frontend Only

npm run build:client

Build Backend Only

npm run build:server

Performance Optimization

Frontend

Backend

Database

Recommended indexes:

CREATE INDEX idx_ocr_jobs_status ON ocr_jobs(status);
CREATE INDEX idx_ocr_jobs_created_at ON ocr_jobs(created_at);
CREATE INDEX idx_ocr_files_job_id ON ocr_files(job_id);

Documentation

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Make your changes
  4. Run tests: npm run test
  5. Commit: git commit -m "feat: description"
  6. Push: git push origin feature/your-feature
  7. Open a Pull Request

Common Tasks

Migrate Database

# Generate migration
npm run typeorm:migration:generate -- -n AddNewColumn

# Run migrations
npm run typeorm:migration:run

Update Dependencies

# Check for updates
npm outdated

# Update specific package
npm update @nestjs/core

# Update all
npm update

Reset Database

rm data/db/ocr.sqlite
npm run typeorm:migration:run

Troubleshooting

“Cannot find module” errors

rm -rf node_modules package-lock.json
npm install

Port conflicts

lsof -i :3000  # Find process
kill -9 <PID>

Redis connection issues

redis-cli ping  # Should return PONG
ps aux | grep redis  # Check if running

Resources