Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:

env:
DJANGO_SETTINGS_MODULE: the_inventory.settings.dev
PYTHONPATH: ${{ github.workspace }}/src:${{ github.workspace }}

steps:
- name: Check out repository
Expand All @@ -36,14 +37,17 @@ jobs:
pip install -r requirements-dev.txt

- name: Run Django checks
working-directory: src
run: python manage.py check

- name: Run tests
run: python manage.py test
working-directory: src
run: python manage.py test tests

- name: Check for missing migrations
working-directory: src
run: python manage.py makemigrations --check --dry-run

- name: Run Ruff
run: ruff check .
run: ruff check src tests

70 changes: 46 additions & 24 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,25 @@ Thank you for your interest in contributing! This guide will help you get starte
pip install -r requirements-dev.txt # Ruff and other dev tools
```

4. **Run migrations:**
4. **Run Django commands from `src/`** (where `manage.py` lives). The repo root holds `seeders/` and `tests/`; loading `the_inventory` adjusts `sys.path` so `INSTALLED_APPS` and the test suite resolve. From the repository root:

```bash
cd src
```

5. **Run migrations:**

```bash
python manage.py migrate
```

5. **Create a superuser** (for accessing the Wagtail admin):
6. **Create a superuser** (for accessing the Wagtail admin):

```bash
python manage.py createsuperuser
```

6. **Start the development server:**
7. **Start the development server:**

```bash
python manage.py runserver
Expand All @@ -69,7 +75,7 @@ The project supports flexible environment configuration for different setups:
| Context | Configuration | Details |
|---------|---------------|---------|
| **Local Development** | Default (dev settings) | No `.env` needed; SQLite, DEBUG=True, localhost CORS |
| **Local with `.env`** | Copy `.env.example` to `.env.local` | Override defaults for testing production-like setups |
| **Local with `.env`** | `.env` at **repository root** (optional) | Backend loads it via settings; copy from `.env.example` as needed |
| **Docker/Containers** | Platform environment variables | Set via Render, Docker Compose, K8s, etc. |
| **Frontend (Next.js)** | `.env.local` in `frontend/` | Must have `NEXT_PUBLIC_API_URL` pointing to backend |

Expand All @@ -83,17 +89,20 @@ For complete setup instructions, environment variables reference, and troublesho
## Project Layout

```
the_inventory/ # Project config (settings, URLs, WSGI)
├── settings/
│ ├── base.py # Shared settings (all environments)
│ ├── dev.py # Development (DEBUG=True, SQLite)
│ └── production.py # Production (ManifestStaticFilesStorage)
home/ # Home page app
search/ # Site-wide search
src/
├── manage.py
├── the_inventory/ # Project config (settings, URLs, WSGI)
│ └── settings/ # base, dev, production
├── api/, home/, inventory/, procurement/, reports/, sales/, search/, tenants/
└── locale/

seeders/ # Django app + seeding commands (repo root)
tests/ # Django / pytest-style tests (repo root)
frontend/ # Next.js app
docs/ # Documentation (Roadmap, Architecture)
```

New feature apps (e.g. `inventory/`, `procurement/`) are created at the project root alongside `home/` and `search/`.
New Django apps live under **`src/`** next to the other apps. The **`seeders`** package stays at the repository root by design.

## Branching Strategy

Expand All @@ -116,24 +125,36 @@ New feature apps (e.g. `inventory/`, `procurement/`) are created at the project

## Running Tests & Checks

From **`src/`** (after `cd src`):

```bash
python manage.py test
python manage.py test tests
python manage.py check
python manage.py makemigrations --check --dry-run
```

Before submitting a PR, also verify:
The test suite lives in the top-level **`tests`** package (repo root), not inside an installed app, so pass the **`tests`** label (or a dotted path such as `tests.api`) so Django discovers `TestCase` modules.

**Ruff** is run from the **repository root** so paths match CI:

```bash
# Django system checks
python manage.py check
cd .. # if you are still inside src/
ruff check src tests seeders
```

# Ensure no missing migrations
python manage.py makemigrations --check --dry-run
CI sets `PYTHONPATH=<workspace>/src:<workspace>` and uses `working-directory: src` for Django steps. Locally, `cd src && python manage.py …` is enough because importing `the_inventory` adds the repo root and `src` to `sys.path`.

When adding new features, **include tests** under the top-level **`tests/`** package (mirroring the app or domain you are changing).

# Ruff linting (matches CI)
ruff check .
### Docker

From the repository root, build the image to confirm the Dockerfile and entrypoint (migrate + Gunicorn from `src/`) still work:

```bash
docker build -t the_inventory .
```

When adding new features, **include tests**. Place them in `<app>/tests.py` or `<app>/tests/` for larger test suites.
See [README — Docker](README.md#docker) for `docker run` examples and environment variables.

## Submitting a Pull Request

Expand All @@ -151,9 +172,10 @@ When adding new features, **include tests**. Place them in `<app>/tests.py` or `

### PR Checklist

- [ ] Tests pass (`python manage.py test`)
- [ ] No missing migrations (`python manage.py makemigrations --check --dry-run`)
- [ ] `python manage.py check` reports no issues
- [ ] Tests pass (`cd src && python manage.py test tests`)
- [ ] No missing migrations (`cd src && python manage.py makemigrations --check --dry-run`)
- [ ] `cd src && python manage.py check` reports no issues
- [ ] Ruff clean from repo root (`ruff check src tests seeders`)
- [ ] New features include tests
- [ ] New models include migrations
- [ ] Documentation updated if needed
Expand Down
9 changes: 6 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ EXPOSE 8000 10000
# 2. Set PORT variable that is used by Gunicorn. This should match "EXPOSE"
# command.
ENV PYTHONUNBUFFERED=1 \
PORT=8000
PORT=8000 \
PYTHONPATH=/app/src:/app

# Install system packages required by Wagtail and Django.
RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \
Expand All @@ -26,9 +27,9 @@ RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-r

# Install the project requirements (includes gunicorn).
COPY requirements.txt /
RUN pip install -r /requirements.txt
RUN pip install --root-user-action=ignore -r /requirements.txt

# Use /app folder as a directory where the source code is stored.
# Repo root at /app (seeders, tests, frontend); Django project in /app/src.
WORKDIR /app

# Set this directory to be owned by the "wagtail" user. This Wagtail project
Expand All @@ -46,6 +47,8 @@ USER wagtail
# Collect static files using the same STORAGES["staticfiles"] as production
# (ManifestStaticFilesStorage). Default manage.py uses dev settings, which
# skips the manifest; runtime then raises "Missing staticfiles manifest entry".
WORKDIR /app/src

RUN DJANGO_SETTINGS_MODULE=the_inventory.settings.production \
SECRET_KEY=collectstatic-build-only-not-used-at-runtime \
python manage.py collectstatic --noinput --clear
Expand Down
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn the_inventory.wsgi:application
web: cd src && gunicorn the_inventory.wsgi:application
47 changes: 29 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
```

Django’s `manage.py` and the project package live under **`src/`**. The repository root also holds `seeders/` and `tests/`; run Django from `src` so imports resolve correctly (this matches CI and Docker).

```bash
cd src
```

### 4. Run database migrations

```bash
Expand Down Expand Up @@ -87,6 +93,8 @@ Visit [http://localhost:8000](http://localhost:8000) for the site, or [http://lo

## Docker

The image copies the full repository to `/app`, sets `PYTHONPATH=/app/src:/app`, and the entrypoint runs migrations and Gunicorn from **`/app/src`** (same layout as local `cd src`).

Build and run using Docker:

```bash
Expand All @@ -105,21 +113,22 @@ For complete environment variable documentation and deployment guides (Docker, R
## Project Structure

```
the_inventory/ # Project configuration (settings, URLs, WSGI)
├── settings/
│ ├── base.py # Shared settings
│ ├── dev.py # Development overrides (DEBUG=True)
│ └── production.py # Production overrides
├── templates/ # Project-level templates (base, 404, 500)
└── static/ # Project-level static files

home/ # Landing / home page app
search/ # Site-wide search app
inventory/ # [Phase 1] Core inventory (products, stock, movements)
src/
├── manage.py # Django entry point (run commands from this directory)
├── the_inventory/ # Project configuration (settings, URLs, WSGI)
│ ├── settings/
│ ├── templates/
│ └── static/
├── api/, home/, inventory/, procurement/, reports/, sales/, search/, tenants/ # Django apps
└── locale/ # Backend translation catalogs

seeders/ # Seeding app (management commands) — repo root
tests/ # Test suite — repo root
frontend/ # Next.js tenant UI
docs/ # Project documentation (Architecture, Roadmap)
```

See [Architecture](docs/ARCHITECTURE.md) for the full technical design, including the Phase 1 schema and future apps (`procurement/`, `sales/`, `reports/`, `api/`).
See [Architecture](docs/ARCHITECTURE.md) for the full technical design, including the Phase 1 schema and app boundaries.

## Project Docs & Meta

Expand All @@ -138,14 +147,16 @@ Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md)

This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).

Our CI workflow runs on pushes and pull requests to `main`, and will:
Our CI workflow runs on pushes and pull requests to `main` and `develop`, and will:

- Run `python manage.py check`
- Run `python manage.py test`
- Run `python manage.py makemigrations --check --dry-run`
- Run `ruff check .`
- Set `PYTHONPATH` to `<repo>/src:<repo>` (so `seeders` and `tests` import correctly)
- From **`src/`**:
- Run `python manage.py check`
- Run `python manage.py test tests`
- Run `python manage.py makemigrations --check --dry-run`
- From the repo root: `ruff check src tests seeders`

You can run the same commands locally using the instructions in `CONTRIBUTING.md` (including installing dev dependencies from `requirements-dev.txt`).
You can mirror that locally with `cd src && python manage.py …` and `ruff check src tests seeders` from the repository root; see [Contributing](CONTRIBUTING.md) (install dev tools from `requirements-dev.txt`).

## License

Expand Down
4 changes: 4 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#!/bin/sh
set -xe

# Django lives in src/ (repo root is parent of this script in Docker: /app).
APP_ROOT=$(cd "$(dirname "$0")" && pwd)
cd "$APP_ROOT/src" || exit 1

# Ensure environment variables are set with fallbacks
export DJANGO_SETTINGS_MODULE="${DJANGO_SETTINGS_MODULE:-the_inventory.settings.production}"
export DATABASE_URL="${DATABASE_URL}"
Expand Down
5 changes: 4 additions & 1 deletion frontend/public/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,10 @@
"pickDate": "اختر تاريخًا",
"all": "الكل",
"selectMethod": "اختر الطريقة",
"selectPeriod": "اختر الفترة"
"selectPeriod": "اختر الفترة",
"csv": "CSV",
"pdf": "PDF",
"emptyDefault": "لا توجد بيانات لهذا التقرير."
},
"filters": {
"valuationMethod": "طريقة التقييم",
Expand Down
5 changes: 4 additions & 1 deletion frontend/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,10 @@
"pickDate": "Pick a date",
"all": "All",
"selectMethod": "Select method",
"selectPeriod": "Select period"
"selectPeriod": "Select period",
"csv": "CSV",
"pdf": "PDF",
"emptyDefault": "No data for this report."
},
"filters": {
"valuationMethod": "Valuation Method",
Expand Down
5 changes: 4 additions & 1 deletion frontend/public/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,10 @@
"pickDate": "Elegir fecha",
"all": "Todos",
"selectMethod": "Seleccionar método",
"selectPeriod": "Seleccionar período"
"selectPeriod": "Seleccionar período",
"csv": "CSV",
"pdf": "PDF",
"emptyDefault": "No hay datos para este informe."
},
"filters": {
"valuationMethod": "Método de valoración",
Expand Down
5 changes: 4 additions & 1 deletion frontend/public/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1936,7 +1936,10 @@
"pickDate": "Choisir une date",
"all": "Tous",
"selectMethod": "Choisir la méthode",
"selectPeriod": "Choisir la période"
"selectPeriod": "Choisir la période",
"csv": "CSV",
"pdf": "PDF",
"emptyDefault": "Aucune donnée pour ce rapport."
},
"filters": {
"valuationMethod": "Méthode de valorisation",
Expand Down
Loading
Loading