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 |