Quorentra

Quorentra CRM Project Setup: Building from Zero — Part 3

Series: Building Quorentra CRM from Zero — A Modular, ChatGPT-Native AI CRM

Creating the canonical Quorentra repository, development environment, backend workspace, frontend workspace, configuration structure, and first reproducible project checkpoint.

Quorentra CRM Project Setup: Building from Zero — Part 3
Quorentra CRM Project Setup: Building from Zero — Part 3

1. Introduction

In Part 1, we defined the Quorentra MVP.

In Part 2, we designed the complete technical architecture.

Now we start building.

This article creates the canonical Quorentra project repository that the rest of the series will use.

That makes Part 3 more important than it may initially appear.

A poor project structure creates friction throughout the entire development lifecycle.

It causes problems such as:

  • Python import errors;
  • unclear module boundaries;
  • duplicated configuration;
  • misplaced tests;
  • frontend/backend confusion;
  • inconsistent environment variables;
  • accidental secrets in Git;
  • difficult Dockerization later;
  • unclear paths in tutorial articles.

We are going to prevent those problems early.

The objective of this article is not yet to build the CRM.

The objective is to create a clean, reproducible development foundation.

By the end of this article, we will have:

quorentra/
├── backend/
├── frontend/
├── mcp/
├── scripts/
├── docs/
├── docker/
├── .env.example
├── .gitignore
└── README.md

We will also have:

  • Git initialized;
  • Python virtual environment created;
  • backend workspace prepared;
  • frontend workspace prepared;
  • environment configuration convention established;
  • project paths standardized;
  • a known Git checkpoint.

This becomes the baseline for every article that follows.


2. Starting Assumptions

This series assumes a local Windows 11 development environment.

You should have the following installed:

Later parts will introduce:

We will not install every future dependency now.

A core principle of this series is:

Install infrastructure when the current development stage actually needs it.

That keeps the project understandable.


3. Choose the Project Location

Choose a directory where you keep development projects.

For example:

C:\Users\<your-user>\Documents\GitHub

Open PowerShell and navigate there:

cd C:\Users\<your-user>\Documents\GitHub

Replace <your-user> with your Windows username.

Create the Quorentra directory:

mkdir quorentra

Enter it:

cd quorentra

Confirm the current directory:

Get-Location

You should see a path ending in:

\quorentra

This directory becomes the repository root.


4. Initialize Git

Initialize the repository:

git init

Check the repository:

git status

You should see that Git is tracking an empty repository.

We will make our first commit later in this article.


5. Define the Canonical Repository Structure

Create the top-level directories:

mkdir backend
mkdir frontend
mkdir mcp
mkdir scripts
mkdir docs
mkdir docker

The repository should now look like:

quorentra/
├── backend/
├── frontend/
├── mcp/
├── scripts/
├── docs/
└── docker/

These directories have clear responsibilities.


6. Directory Responsibilities

backend

Contains the Python/FastAPI application.

Eventually:

backend/
├── app/
└── tests/

The backend will contain:

  • API routes;
  • domain modules;
  • application services;
  • persistence logic;
  • authentication;
  • tenant context;
  • AI services;
  • workflows.

frontend

Contains the React and TypeScript application.

Eventually:

frontend/
└── src/

The frontend will provide the conventional CRM web interface.


mcp

Contains Quorentra’s MCP-facing application layer.

This will later expose CRM capabilities to ChatGPT.

We create the directory now so that the architectural boundary is visible from the start, but we will not implement MCP yet.


scripts

Contains utility scripts.

Examples later may include:

scripts/
├── test_connection.py
├── seed_data.py
└── maintenance/

Scripts are not application modules.

They are developer and operational utilities.


docs

Contains technical project documentation.

Examples:

docs/
├── architecture/
├── adr/
└── development/

Later, Architectural Decision Records can live here.


docker

Contains container-related configuration when Docker is introduced.

We are creating the boundary now but deliberately postponing implementation.


7. Create the Backend Structure

Move into the backend directory:

cd backend

Create the application directory:

mkdir app

Create the test directory:

mkdir tests

The structure becomes:

backend/
├── app/
└── tests/

Now create the initial Python package file.

From PowerShell:

New-Item app\__init__.py -ItemType File

This file can remain empty for now.

The presence of:

app/__init__.py

makes the app directory an explicit Python package.

That will help keep imports predictable throughout the series.


8. Why the Python Package Structure Matters

Later, we will use imports such as:

from app.main import app

and:

from app.db.session import engine

For those imports to work reliably, we must run Python commands from the correct working directory and maintain a consistent package structure.

Our intended backend structure will evolve toward:

backend/
└── app/
├── __init__.py
├── main.py
├── api/
├── core/
├── db/
└── modules/

The backend directory is the Python application workspace.

That means future commands such as:

pytest

or:

uvicorn app.main:app --reload

will generally be executed from:

quorentra\backend

This is a convention we will keep throughout the series.


9. Create the Python Virtual Environment

Still inside:

quorentra\backend

create a virtual environment:

python -m venv .venv

The backend structure becomes:

backend/
├── .venv/
├── app/
└── tests/

Activate the environment:

.\.venv\Scripts\Activate.ps1

Your PowerShell prompt should now begin with something similar to:

(.venv)

For example:

(.venv) PS C:\Users\<your-user>\Documents\GitHub\quorentra\backend>

10. If PowerShell Blocks Virtual Environment Activation

Some Windows installations prevent PowerShell scripts from running.

If you see an execution-policy error, inspect the current policy:

Get-ExecutionPolicy

A common development configuration is:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

Then retry:

.\.venv\Scripts\Activate.ps1

Only change PowerShell execution policy if you understand and accept the implications for your environment.

Alternatively, Command Prompt can activate the environment with:

.venv\Scripts\activate.bat

11. Verify the Python Interpreter

Run:

python --version

Then:

where.exe python

The first Python path should point into:

backend\.venv\Scripts\python.exe

This verifies that the virtual environment is active.

This is especially important when working in VS Code.

A common cause of unresolved imports is that VS Code uses a different Python interpreter from the terminal.

Later, when opening the project in VS Code, make sure the selected interpreter is:

quorentra\backend\.venv\Scripts\python.exe

12. Upgrade pip

Upgrade the package installer inside the virtual environment:

python -m pip install --upgrade pip

Confirm:

pip --version

We now have an isolated Python environment ready for FastAPI dependencies in the next article.


13. Do Not Install FastAPI Yet

It may seem natural to install:

fastapi
uvicorn
sqlalchemy
alembic
psycopg

immediately.

We are deliberately not doing that yet.

Part 4 will introduce the first FastAPI application and install exactly the backend packages required for that checkpoint.

This keeps the dependency history understandable.

Each dependency should have a reason for existing.


14. Return to the Repository Root

Deactivate the virtual environment if desired:

deactivate

Return to the repository root:

cd ..

You should now be back at:

quorentra

15. Prepare the Frontend Workspace

We are not creating the full React application yet.

That will happen in the dedicated frontend foundation article.

For now, create a placeholder README:

New-Item frontend\README.md -ItemType File

Later, Vite will populate the directory with the React project.

Why not initialize React immediately?

Because we want each article to have one primary concern.

Part 3 establishes the repository and environment.

The frontend article will establish React properly, verify Node/npm versions, explain the generated structure, and connect the application to FastAPI.


16. Prepare the MCP Workspace

Create a placeholder file:

New-Item mcp\README.md -ItemType File

Eventually this directory will contain the ChatGPT-facing MCP implementation.

For now, it documents an intentional architectural boundary.


17. Prepare the Documentation Structure

Create architecture and ADR directories:

mkdir docs\architecture
mkdir docs\adr
mkdir docs\development

The structure becomes:

docs/
├── architecture/
├── adr/
└── development/

18. Architectural Decision Records

ADR stands for Architectural Decision Record.

We identified several important decisions in Part 2.

Examples include:

ADR-001 Modular Monolith First
ADR-002 PostgreSQL as System of Record
ADR-003 Shared Schema Multi-Tenancy
ADR-004 Application Services Own Use Cases
ADR-005 Thin Interfaces
ADR-006 React Is Not the Business Layer
ADR-007 MCP Is Not a Second Backend
ADR-008 ChatGPT Is a First-Class Interface

We do not need to create all ADR documents today.

But the location already exists:

docs/adr/

As architectural choices become concrete during implementation, we can record them there.


19. Create the Environment File Strategy

At the repository root, create:

New-Item .env.example -ItemType File

The .env.example file contains configuration names but no secrets.

For now, add:

APP_ENV=development
BACKEND_HOST=127.0.0.1
BACKEND_PORT=8000
FRONTEND_HOST=127.0.0.1
FRONTEND_PORT=5173

We will add database settings when PostgreSQL integration is implemented.

Later, this file may grow to contain names such as:

DATABASE_URL=
SECRET_KEY=
OPENAI_API_KEY=

But real secret values should never be stored in .env.example.


20. Local .env

Create the actual local environment file:

Copy-Item .env.example .env

You now have:

.env
.env.example

The difference is important.

.env.example

Safe to commit.

Contains example configuration names.

.env

Local machine configuration.

May contain secrets.

Must not be committed.


21. Create .gitignore

At the repository root:

New-Item .gitignore -ItemType File

Add:

# Environment
.env
# Python
__pycache__/
*.py[cod]
*.pyo
*.pyd
.Python
.pytest_cache/
.mypy_cache/
.ruff_cache/
.coverage
htmlcov/
# Virtual environments
.venv/
venv/
# Node
node_modules/
dist/
.vite/
# IDEs
.vscode/
.idea/
# OS files
.DS_Store
Thumbs.db
# Logs
*.log
# Temporary files
*.tmp
*.temp
# Coverage
coverage/
# Build
build/
# Local database or runtime artifacts
*.db

This prevents common development artifacts from being committed accidentally.


22. Should .vscode Always Be Ignored?

Not necessarily.

Some projects intentionally commit:

.vscode/settings.json
.vscode/extensions.json

to standardize the development environment.

For the MVP, we will initially ignore .vscode.

Later, if we decide that shared workspace settings add value, we can explicitly include selected files.


23. Create the Root README

At the repository root:

New-Item README.md -ItemType File

Add:

# Quorentra
Quorentra is a modular, ChatGPT-native AI CRM.
This repository accompanies the series:
**Building Quorentra CRM from Zero — A Modular, ChatGPT-Native AI CRM**
## Architecture
Quorentra is designed around:
- React
- TypeScript
- FastAPI
- PostgreSQL
- SQLAlchemy
- Alembic
- MCP
- OpenAI Apps SDK
- ChatGPT
- pgvector
The system follows a modular-monolith architecture for the MVP.
Quorentra remains the system of record, while ChatGPT acts as a first-class intelligent interaction layer.
## Repository Structure
```text
quorentra/
├── backend/
├── frontend/
├── mcp/
├── scripts/
├── docs/
├── docker/
├── .env.example
├── .gitignore
└── README.md

Development Status

Current milestone:

Project foundation

Next milestone:

Minimum FastAPI application


This README will evolve with the project.

---

# 24. Create the Initial Backend README

Add useful context inside:

```text
backend/README.md


From the repository root:

New-Item backend\README.md -ItemType File

Add:

# Quorentra Backend
The Quorentra backend is built with Python and FastAPI.
Application package:
```text
backend/app/

Tests:

backend/tests/

Backend commands should generally be run from:

quorentra/backend

This small piece of documentation helps prevent working-directory confusion later.

---

# 25. Update the Frontend README

Edit:

```text
frontend/README.md


and add:

# Quorentra Frontend
The Quorentra frontend will be built with React, TypeScript, and Vite.
The frontend will provide the conventional CRM web application.
ChatGPT will act as a separate first-class interaction surface through the Quorentra MCP and Apps SDK integration.

26. Update the MCP README

Edit:

mcp/README.md

and add:

# Quorentra MCP
This directory will contain the Model Context Protocol integration used to expose approved Quorentra capabilities to ChatGPT.
MCP is an interface layer.
It must not bypass Quorentra application services, authorization, tenant isolation, or business rules.

This documents one of the most important architecture rules from Part 2 directly inside the repository.


27. Add a Scripts README

Create:

New-Item scripts\README.md -ItemType File

Add:

# Quorentra Scripts
This directory contains developer and operational utility scripts.
Examples may later include:
- database connectivity tests;
- development setup utilities;
- seed-data scripts;
- migration helpers;
- maintenance scripts.
Scripts should import Quorentra application code through the canonical backend package structure.

28. The Repository Structure So Far

Your repository should now resemble:

quorentra/
├── backend/
│ ├── .venv/
│ ├── app/
│ │ └── __init__.py
│ ├── tests/
│ └── README.md
├── frontend/
│ └── README.md
├── mcp/
│ └── README.md
├── scripts/
│ └── README.md
├── docs/
│ ├── architecture/
│ ├── adr/
│ └── development/
├── docker/
├── .env
├── .env.example
├── .gitignore
└── README.md

Remember:

backend/.venv/
.env

exist locally but should not appear in Git.


29. Verify .gitignore

Run:

git status

You should see files such as:

.env.example
.gitignore
README.md
backend/
frontend/
mcp/
scripts/

You should not see:

.env
backend/.venv/

If you do, stop and correct .gitignore before committing.


30. Check Python from VS Code

If you use VS Code, open the project from the repository root:

code .

Then use:

Ctrl + Shift + P

Search for:

Python: Select Interpreter

Select:

backend\.venv\Scripts\python.exe

This will become important once FastAPI imports are introduced.

A wrong interpreter can produce errors such as:

Import "fastapi" could not be resolved

even when FastAPI is installed correctly in the project virtual environment.


31. Working Directory Convention

We should establish this rule now.

Repository-level commands

Run from:

quorentra/

Examples:

git status
git add .
git commit

Backend commands

Run from:

quorentra/backend/

Examples later:

pytest
uvicorn app.main:app --reload
alembic upgrade head

Frontend commands

Run from:

quorentra/frontend/

Examples later:

npm install
npm run dev
npm run build

This convention will eliminate a large class of avoidable path errors.


32. Why from app... Sometimes Fails

Suppose later we have:

from app.main import app

and run a script from:

quorentra/

Python may not know that:

quorentra/backend

is the import root.

But when running from:

quorentra/backend

Python sees:

app/

directly.

Therefore:

from app.main import app

works naturally.

This is why our command-location convention matters.

We will also design scripts and tests carefully so developers do not have to constantly manipulate PYTHONPATH.


33. Do Not Add sys.path Hacks

A common workaround is to add code like:

import sys
sys.path.append(...)

to make imports work.

We should avoid this.

If imports fail, the first questions should be:

  1. Is the Python interpreter correct?
  2. Is the command being run from the intended directory?
  3. Is the package structure correct?
  4. Is the module actually installed or importable?

Path manipulation should be the exception, not the architecture.


34. Verify Git

Run:

git status

Review every file that will be committed.

Then stage the foundation:

git add .

Check again:

git status

Make sure .env and .venv are absent.


35. First Git Commit

Create the first project checkpoint:

git commit -m "chore: initialize Quorentra project structure"

If Git asks for your identity, configure it:

git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"

Then retry the commit.


36. Create a Development Branch Strategy

For a small MVP project, we do not need an elaborate GitFlow model.

A simple strategy is sufficient.

Keep:

main

stable.

Use short-lived feature branches when appropriate:

feature/fastapi-foundation
feature/database-foundation
feature/react-foundation
feature/company-module

For solo development, direct development on main is possible, but feature branches become increasingly useful as the system grows.

The important point is not process complexity.

It is maintaining meaningful checkpoints.


37. Optional: Create a Remote GitHub Repository

If you want Quorentra hosted on GitHub, create an empty repository named:

quorentra

Do not initialize it with another README if the local repository already contains one.

Then connect the remote:

git remote add origin <repository-url>

Verify:

git remote -v

Push:

git branch -M main
git push -u origin main

The repository is now backed up remotely.


38. Version the Project

We will use milestone-style versions throughout the series.

The current codebase is not yet MVO 0.1.

It is the project foundation.

We can think of it as:

Quorentra 0.0.1

The next milestones will gradually become:

0.0.2 — FastAPI running
0.0.3 — PostgreSQL connected
0.0.4 — React running
0.1.0 — MVO complete

Exact version numbers may evolve, but milestone thinking is useful.

It ensures that each article produces a clearly identifiable state.


39. Verify the Complete Project

Before concluding the article, verify the repository.

From:

quorentra/

run:

git status

Expected result:

nothing to commit, working tree clean

Then verify the backend environment:

cd backend
.\.venv\Scripts\Activate.ps1
python --version

Verify pip:

pip --version

Then deactivate:

deactivate

Return to the root:

cd ..

At this point, the foundation is complete.


40. Acceptance Criteria

Part 3 is complete when all of the following are true:

✓ Quorentra repository exists
✓ Git is initialized
✓ Canonical top-level directories exist
✓ backend/app is a Python package
✓ Python virtual environment works
✓ VS Code can use the project interpreter
✓ frontend workspace exists
✓ MCP workspace exists
✓ documentation directories exist
✓ .env.example exists
✓ local .env is ignored
✓ .venv is ignored
✓ README files document responsibilities
✓ Git working tree is clean
✓ First commit exists

No CRM functionality exists yet.

That is intentional.

We have created the foundation on which the CRM will be built.


41. Troubleshooting

python Is Not Recognized

Verify that Python is installed and available in PATH:

python --version

If not, reinstall Python or correct the Windows PATH configuration.


code Is Not Recognized

The VS Code command-line launcher may not be installed in PATH.

You can still open the project manually in VS Code using:

File → Open Folder

and select the quorentra directory.


Virtual Environment Will Not Activate

Check PowerShell execution policy:

Get-ExecutionPolicy

Or use Command Prompt:

.venv\Scripts\activate.bat

Wrong Python Interpreter in VS Code

Use:

Ctrl + Shift + P
→ Python: Select Interpreter

and select:

backend\.venv\Scripts\python.exe

.env Appears in git status

Check that .gitignore contains:

.env

If .env was already staged:

git restore --staged .env

If it had previously been committed, additional Git cleanup will be required.

Never push secrets to a public repository.


.venv Appears in Git

Make sure .gitignore includes:

.venv/

If necessary:

git restore --staged backend/.venv

42. What We Deliberately Did Not Do

Part 3 did not:

  • install FastAPI;
  • create main.py;
  • install SQLAlchemy;
  • connect PostgreSQL;
  • configure Alembic;
  • create React with Vite;
  • configure MCP;
  • configure OpenAI;
  • create CRM tables;
  • write business logic.

This restraint is intentional.

The project now has a stable base, and every following article can introduce one coherent capability.


43. The Development State

Our development path currently looks like:

Architecture
Repository
FastAPI
PostgreSQL
React
Identity
CRM
ChatGPT
AI

We have reached the first implementation checkpoint.


44. Next Article

In Part 4, we will create the first running FastAPI application.

We will install the minimum backend dependencies, introduce:

backend/
└── app/
├── __init__.py
└── main.py

and build the first endpoint:

GET /api/v1/health

The acceptance criterion will be simple:

HTTP 200 OK

with a structured response showing that the Quorentra API is running.

We will also establish:

  • FastAPI application creation;
  • API versioning;
  • development server execution;
  • basic application metadata;
  • a first automated API test;
  • the canonical Uvicorn command;
  • correct Python import behavior.

Part 4 will therefore deliver the first actual running Quorentra component:

Developer
FastAPI
/api/v1/health

From that point forward, Quorentra is no longer just an architecture.

It is running software.

Quorentra

Contact

Menu

Designed with WordPress

Discover more from Quorentra

Subscribe now to keep reading and get access to the full archive.

Continue reading