Skip to content

003 — Repositories and Structure

Repository Map

flowchart TB
    ERP["<b>ERP main repo</b><br/>owned by ERP Team<br/>connected to Odoo.sh<br/>holds the 5 deployment branches"]
    B2B["<b>addons_lp_ecommerce</b><br/>owned by B2B Team<br/>Odoo custom modules<br/>embedded as a Git submodule"]
    NEXT["<b>next_ecommerce</b><br/>owned by B2B Team<br/>Next.js portals<br/>independent repo + Docker pipeline"]

    B2B -->|"git submodule pointer<br/>updated by ERP Team"| ERP
    ERP -->|"builds"| SH[["Odoo.sh environments"]]
    NEXT -->|"docker image → private registry"| SRV[["Portal containers"]]
    SRV -.->|"REST + WS"| SH

Two repositories are actively developed; a third (the ERP main repo) is the deployment vehicle and is owned by the ERP team. The B2B team never pushes to Odoo.sh directly.

Repo Path in the working tree Contents Deployed as
Odoo addons addons_lp_ecommerce/ 4 Odoo modules + developer docs Git submodule of the ERP repo → Odoo.sh
Portal app next_ecommerce/ Next.js 15 application, Docker envs, Cloudflare config, release notes Production: Cloudflare Worker, auto-deployed from GitHub main. Non-production: linux/amd64 image → private registry → containers

addons_lp_ecommerce/ — Odoo Side

addons_lp_ecommerce/
├── lp_base/                  Technical foundation (no business logic)
├── access_management/        Role & permission engine (AMM)
├── ecommerce_access_data/    Pre-loaded AMM catalogue for this platform
├── ecommerce/                The B2B business module  ← ~90 % of the code
└── _docs/                    Developer documentation, case studies, Postman collection

Inside ecommerce/

Folder Responsibility
controllers/ Customer Portal REST routes (/ecommerce/api/*) — 14 files, thin
controllers_admin/ Account Management Portal REST routes — 15 files, thin
models/ All business logic, validation, tenancy scoping, API serialisation
views/ Odoo ERP Back Office forms, lists, searches, actions, menus
security/ Groups (groups.xml) and model access rules (ir.model.access.csv)
data/ Sequences, mail templates, scheduled job
report/ User invitation QR-code PDF report
wizard/ JSON product import wizard
static/ ERP Back Office assets: B2B dashboard OWL component, chat widget, SCSS
tests/ Module tests
_docs/ Module-level developer notes

Scale reference: ~14 200 lines of Python. The three largest models carry most of the domain: product_template.py (~2 140 lines, catalog + admin product management + import), sale_order.py (~1 315, the order state machine), res_users.py (~1 100, identity, password reset, invitations, portal user management).


next_ecommerce/ — Portal Side

next_ecommerce/
├── src/
│   ├── app/                 App Router pages — the routing surface
│   ├── components/          UI: guards, layout, feature components, primitives
│   ├── infrastructure/      API services, HTTP client, WebSocket, storage, logging
│   ├── stores/              Zustand state, one store per domain
│   ├── shared/              Config, hooks, access codes, libraries
│   ├── services/            Cross-cutting service objects
│   └── types/               Global TypeScript types
├── docker/                  Four deployable environments + build/upload scripts
├── scripts/                 Build-time generators (release history)
├── public/                  Static assets
└── _docs/                   Release notes, rules, component and feature docs

Layer responsibilities

Layer Contains Must not contain
app/ Route definition, guards, page composition Data fetching logic, business rules
components/features/* Feature UI, forms, tables, modals Direct HTTP calls
stores/* State, actions, orchestration of service calls JSX, axios
infrastructure/api/* One folder per domain: *.endpoints.ts, *.service.ts, *.types.ts UI concerns
shared/config Runtime configuration read from NEXT_PUBLIC_* env vars Secrets

The consistent per-domain triple (endpoints / service / types) is the frontend's main structural convention — adding a backend endpoint means adding it in exactly these three places plus a store action.


Ownership and Change Flow

flowchart LR
    DEV["B2B developer"] -->|"PR (Azure DevOps)"| B2BREPO["addons_lp_ecommerce"]
    DEV -->|"PR (Azure DevOps)"| NEXTREPO["next_ecommerce"]

    B2BREPO -->|"submodule pointer<br/>(ERP Team)"| SH["Odoo.sh staging-b2b"]
    NEXTREPO -->|"build_upload_amd64.sh<br/>(B2B Team, manual)"| IMG["registry :staging-b2b"]
    SH --> ENVTEST["Environment tested as one platform"]
    IMG --> ENVTEST

    ENVTEST --> PROMO["promote"]
    PROMO -->|"ERP Team merges<br/>through 3 branches"| PRODBE["Odoo.sh production<br/>www.samtia.com"]
    NEXTREPO -->|"push main to the<br/>GitHub remote — automatic"| PRODFE["Cloudflare Worker<br/>b2b.samtia.com"]

The two halves deploy through different pipelines and are versioned independently. A platform release is therefore a pair: an Odoo.sh build plus a portal build. The portal's release-note files record both (headCommit for the frontend, headCommitBackend for the module) so a pair can be reconstructed later. See 014.

Note the asymmetry in the diagram: the production backend is reached only after three gated promotions, while the production portal is one push away from live. That gap is the main thing to hold in mind when planning a change that spans both.

next_ecommerce has two git remotes: origin (Azure DevOps) for code review, and github (LaplaceSoftware/next_ecommerce) which is what Cloudflare watches. Merging a PR does not deploy; pushing to GitHub main does.