Skip to content

Architecture Decision Records

This document captures key architectural decisions made during the project.

What is an ADR?

An Architecture Decision Record (ADR) documents a significant decision made during the project, including context, options considered, and rationale for the choice.


ADR-001: Use Docker for Deployment

Status

Accepted

Context

Need a consistent, reproducible deployment method for the Odoo ERP system across different environments (development, staging, production).

Options Considered

Option Pros Cons
Docker Compose Consistent environment, easy deployment, isolated services Learning curve, resource overhead
Native Installation Direct access, no container overhead Dependency conflicts, hard to reproduce
Kubernetes Scalable, production-ready Complex for small deployments

Decision

Use Docker Compose for all environments.

Rationale

  • Consistent environment between development and production
  • Easy onboarding for new developers
  • Isolated services prevent conflicts
  • Simple rollback via images
  • Good fit for current scale

Consequences

  • All team members must learn Docker basics
  • Need Docker installed on all machines
  • Some debugging is more complex in containers
  • Resource usage higher than native

ADR-002: Nginx as Reverse Proxy

Status

Accepted

Context

Need a way to route traffic to multiple services (Odoo, PWA, Docs) from a single entry point with SSL termination.

Options Considered

Option Pros Cons
Nginx Fast, mature, well-documented Configuration complexity
Traefik Auto-discovery, dynamic config Less mature, different paradigm
HAProxy High performance More complex configuration
Direct access Simple No SSL termination, multiple ports

Decision

Use Nginx as reverse proxy.

Rationale

  • Industry standard, well-documented
  • Excellent performance
  • Good SSL/TLS support
  • Team familiarity
  • Static file caching

Consequences

  • Need to maintain Nginx configuration
  • Must update config for new services
  • SSL certificate management required

ADR-003: PostgreSQL 15 for Database

Status

Accepted

Context

Odoo requires PostgreSQL. Need to choose version and deployment method.

Options Considered

Option Pros Cons
PostgreSQL 15 (Container) Latest features, containerized Must manage ourselves
PostgreSQL 13 (Container) Stable, tested Older features
AWS RDS Managed, automatic backups Cost, external dependency
PostgreSQL on host Direct access Not isolated, harder to migrate

Decision

  • Development: PostgreSQL 15 in Docker
  • Production: Consider AWS RDS

Rationale

  • PostgreSQL 15 has performance improvements
  • Container provides isolation in development
  • RDS for production offloads backup/scaling concerns

Consequences

  • Need backup strategy for containerized DB
  • May have slight version differences dev/prod
  • RDS adds infrastructure cost

ADR-004: Flask for PWA Backend

Status

Accepted

Context

Need a lightweight backend for the field service Progressive Web App that communicates with Odoo.

Options Considered

Option Pros Cons
Flask Lightweight, Python, flexible Need to build structure
Django Batteries included Heavy for simple API proxy
Node.js/Express Fast, good for real-time Different language from Odoo
Odoo Website Native integration Heavy, less flexible

Decision

Use Flask with Gunicorn for production.

Rationale

  • Same language as Odoo (Python)
  • Lightweight for API proxy use case
  • Easy to understand and modify
  • Good PWA support with service workers

Consequences

  • Need to handle session management
  • Must build authentication integration
  • Separate deployment from Odoo

ADR-005: MkDocs Material for Documentation

Status

Accepted

Context

Need a documentation system that is easy to maintain and provides good navigation/search.

Options Considered

Option Pros Cons
MkDocs Material Beautiful, searchable, markdown Build step required
Sphinx Python standard, powerful Complex RST format
GitBook Nice UI, collaboration External service
Wiki Easy editing Poor organization
README files No build needed No navigation/search

Decision

Use MkDocs with Material theme.

Rationale

  • Markdown is easy to write
  • Material theme looks professional
  • Good search functionality
  • Can be containerized
  • Navigation structure is clear

Consequences

  • Docs must be rebuilt after changes
  • Need to maintain mkdocs.yml
  • Learning curve for MkDocs features

ADR-006: Module Prefix Naming Convention

Status

Accepted

Context

Need a way to identify custom modules vs. community/core modules.

Options Considered

Option Pros Cons
jdx_ prefix Clear identification Longer names
custom_ prefix Generic Not company-specific
No prefix Shorter names Hard to identify custom
Separate directory Physical separation Path complexity

Decision

Use jdx_ prefix for company custom modules.

Rationale

  • Immediately identifies custom code
  • Follows Odoo community conventions
  • Easy to filter in searches
  • Clear ownership

Consequences

  • All new modules must follow convention
  • Need to migrate any non-prefixed modules
  • Longer module names

ADR-007: REST API Module for External Integration

Status

Accepted

Context

Need to expose Odoo functionality to external systems (PWA, third-party integrations).

Options Considered

Option Pros Cons
Custom REST API module Full control, documented Development effort
Odoo XML-RPC Built-in Complex, not RESTful
OCA REST Framework Community maintained Learning curve
GraphQL Flexible queries Different paradigm

Decision

Use custom REST API module with API key authentication.

Rationale

  • RESTful design is intuitive
  • API key auth is simple and secure
  • Full control over endpoints
  • Good documentation with Swagger

Consequences

  • Must maintain API module
  • Need to document all endpoints
  • Version management for API changes

ADR-008: JustCall for SMS Integration

Status

Accepted

Context

Need SMS/MMS capability for customer communication from Odoo.

Options Considered

Option Pros Cons
JustCall MMS support, good API Cost per message
Twilio Industry standard Complex pricing
AWS SNS AWS ecosystem SMS only, no MMS
Custom SMS gateway Full control High maintenance

Decision

Use JustCall for SMS/MMS integration.

Rationale

  • MMS support required
  • Good API documentation
  • Reliable delivery
  • Call integration possible

Consequences

  • Vendor dependency
  • Per-message costs
  • API key management

ADR-009: S3 for Signature Storage

Status

Accepted

Context

Need reliable storage for digital signature images captured in the field.

Options Considered

Option Pros Cons
AWS S3 Scalable, durable, CDN AWS account needed
Odoo filestore No external service Less scalable, backups complex
Local filesystem Simple Not shared, no redundancy
Azure Blob Similar to S3 Different ecosystem

Decision

Use AWS S3 for signature image storage.

Rationale

  • Highly durable (99.999999999%)
  • Scalable without management
  • CDN for fast delivery
  • Easy backup/lifecycle policies

Consequences

  • AWS account and costs
  • Network dependency
  • Need to handle S3 permissions
  • IAM key management

ADR-010: Semantic Versioning for Modules

Status

Accepted

Context

Need a consistent versioning strategy for modules and releases.

Options Considered

Option Pros Cons
Semantic Versioning Clear meaning, industry standard Discipline required
Date-based versions Easy to understand No indication of change type
Sequential numbers Simple No semantic meaning
Git commit hashes Precise Hard to compare

Decision

Use Semantic Versioning: 15.0.MAJOR.MINOR.PATCH for modules.

Rationale

  • Clear indication of change impact
  • Industry standard
  • Odoo convention compatible
  • Enables automated version checks

Consequences

  • Must evaluate changes for version bump
  • All team members must understand SemVer
  • Documentation needed for version policy

ADR-011: Flask + Tailwind + Alpine.js for Landing Page

Status

Accepted

Context

Need a public-facing landing page to generate leads (estimate requests) and support tickets that integrate with Odoo CRM and Helpdesk modules. The landing page must be: - Fast and SEO-friendly - Mobile responsive - Themeable for multi-company deployment - Integrated with the existing Docker infrastructure

Options Considered

Option Pros Cons
Flask + Tailwind + Alpine.js Lightweight, consistent with PWA, theme support Another service to maintain
Odoo Website Native CRM integration Heavy, less flexible design
Static Site (Hugo/Jekyll) Fast, simple No form processing, separate API needed
Next.js/React Modern, SSR Overkill for landing page, different stack
WordPress Easy content editing PHP stack, security concerns, separate DB

Decision

Use Flask with Tailwind CSS and Alpine.js for the landing page.

Rationale

  • Consistency: Same Python/Flask stack as PWA, familiar patterns
  • Lightweight: Minimal dependencies, fast load times
  • Themeable: CSS variables allow runtime theme switching via .env
  • Alpine.js: Minimal JS for forms without SPA complexity
  • Tailwind CSS: Utility-first CSS, no custom CSS maintenance
  • Docker Integration: Fits existing infrastructure seamlessly

Technical Choices

Component Choice Reason
Backend Flask + Gunicorn Python consistency, production-ready
CSS Framework Tailwind CSS Utility-first, themeable via CSS variables
JavaScript Alpine.js Lightweight reactivity, no build step
Form Protection reCAPTCHA v3 Invisible, no user friction
API Integration Odoo REST API Consistent with PWA approach
Theme System CSS Variables + .env Runtime switching without rebuild

Architecture

┌─────────────────┐     ┌────────────────────┐
│  Landing Page   │────▶│  Odoo REST API     │
│  (Flask:8001)   │     │  (/restapi/1.0/)   │
└─────────────────┘     └────────────────────┘
        │                        │
        ▼                        ▼
┌─────────────────┐     ┌────────────────────┐
│  Google         │     │  crm.lead          │
│  reCAPTCHA v3   │     │  helpdesk.ticket   │
└─────────────────┘     └────────────────────┘

Consequences

  • Additional container in Docker stack
  • Theme configuration via .env for easy multi-company support
  • reCAPTCHA keys required for form protection
  • Odoo API key needed for form submission
  • CSS changes require Tailwind rebuild (npm run build)

ADR Template

Use this template for new ADRs:

## ADR-XXX: Title

### Status
Proposed | Accepted | Deprecated | Superseded

### Context
What is the issue that we're seeing that is motivating this decision?

### Options Considered

| Option | Pros | Cons |
|--------|------|------|
| Option 1 | ... | ... |
| Option 2 | ... | ... |

### Decision
What is the change that we're proposing and/or doing?

### Rationale
Why is this decision being made?

### Consequences
What becomes easier or more difficult because of this change?

Decision Log

ID Title Status Date
ADR-001 Use Docker for Deployment Accepted 2025-01
ADR-002 Nginx as Reverse Proxy Accepted 2025-01
ADR-003 PostgreSQL 15 for Database Accepted 2025-01
ADR-004 Flask for PWA Backend Accepted 2025-01
ADR-005 MkDocs Material for Documentation Accepted 2025-01
ADR-006 Module Prefix Naming Convention Accepted 2025-01
ADR-007 REST API Module for External Integration Accepted 2025-01
ADR-008 JustCall for SMS Integration Accepted 2025-01
ADR-009 S3 for Signature Storage Accepted 2025-01
ADR-010 Semantic Versioning for Modules Accepted 2025-12
ADR-011 Flask + Tailwind + Alpine.js for Landing Page Accepted 2025-12