Skip to content

Commit 4760ede

Browse files
upgrade backend and frontend to latest
1 parent ba1706b commit 4760ede

File tree

136 files changed

+11000
-8444
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+11000
-8444
lines changed

.env

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,18 @@ POSTGRES_PORT=5432
3737
POSTGRES_DB=app
3838
POSTGRES_USER=postgres
3939
POSTGRES_PASSWORD=changethis
40+
# pytest and playwright
41+
POSTGRES_TEST_DB=app_test
4042

4143
SENTRY_DSN=
4244

4345
# Configure these with your own Docker registry images
4446
DOCKER_IMAGE_BACKEND=backend
4547
DOCKER_IMAGE_FRONTEND=frontend
48+
49+
# CICD
50+
CI=
51+
52+
# Frontend tests
53+
VITE_API_URL=http://localhost:8000
54+
MAILCATCHER_HOST=http://localhost:1080

.github/workflows/test-docker-compose.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ on:
1010
- synchronize
1111

1212
jobs:
13-
1413
test-docker-compose:
1514
runs-on: ubuntu-latest
1615
steps:

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
.vscode
1+
.vscode/settings.json
22
node_modules/
33
/test-results/
44
/playwright-report/
55
/blob-report/
66
/playwright/.cache/
7+
/playwright/.auth/

.node-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v20.18.1

.vscode/extensions.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"recommendations": [
3+
"ms-azuretools.vscode-docker",
4+
"ms-python.python",
5+
"charliermarsh.ruff",
6+
"biomejs.biome",
7+
"ms-playwright.playwright"
8+
]
9+
}

.vscode/settings.example.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"biome.lspBin": "./frontend/node_modules/.bin/biome",
3+
"python.defaultInterpreterPath": "${workspaceFolder}/backend/.venv/bin/python",
4+
"python.envFile": "${workspaceFolder}/.env",
5+
"python.testing.cwd": "${workspaceFolder}/backend",
6+
"python.testing.pytestArgs": ["-sv", "${workspaceFolder}/backend/app/tests"],
7+
"python.testing.pytestEnabled": true,
8+
"python.testing.unittestEnabled": false,
9+
"python.analysis.extraPaths": ["${workspaceFolder}/backend"],
10+
"editor.formatOnSave": true,
11+
"editor.codeActionsOnSave": {
12+
"source.organizeImports": "explicit",
13+
"source.fixAll": "explicit"
14+
},
15+
"[python]": {
16+
"editor.defaultFormatter": "charliermarsh.ruff"
17+
},
18+
"[markdown][yaml]": {
19+
"editor.formatOnSave": false
20+
},
21+
"[json][javascript][javascriptreact][typescript][typescriptreact]": {
22+
"editor.defaultFormatter": "biomejs.biome"
23+
}
24+
}

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
## Technology Stack and Features
77

88
-[**FastAPI**](https://fastapi.tiangolo.com) for the Python backend API.
9-
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).
10-
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
11-
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
9+
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) for the Python SQL database interactions (ORM).
10+
- 🔍 [Pydantic](https://docs.pydantic.dev), used by FastAPI, for the data validation and settings management.
11+
- 💾 [PostgreSQL](https://www.postgresql.org) as the SQL database.
1212
- 🚀 [React](https://react.dev) for the frontend.
13-
- 💃 Using TypeScript, hooks, Vite, and other parts of a modern frontend stack.
14-
- 🎨 [Chakra UI](https://chakra-ui.com) for the frontend components.
15-
- 🤖 An automatically generated frontend client.
16-
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
17-
- 🦇 Dark mode support.
13+
- 💃 Using TypeScript, hooks, Vite, and other parts of a modern frontend stack.
14+
- 🎨 [Chakra UI](https://chakra-ui.com) for the frontend components.
15+
- 🤖 An automatically generated frontend client.
16+
- 🧪 [Playwright](https://playwright.dev) for End-to-End testing.
17+
- 🦇 Dark mode support.
1818
- 🐋 [Docker Compose](https://www.docker.com) for development and production.
1919
- 🔒 Secure password hashing by default.
2020
- 🔑 JWT (JSON Web Token) authentication.

backend/README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ By default, the dependencies are managed with [uv](https://docs.astral.sh/uv/),
1616
From `./backend/` you can install all the dependencies with:
1717

1818
```console
19-
$ uv sync
19+
uv sync
2020
```
2121

2222
Then you can activate the virtual environment with:
2323

2424
```console
25-
$ source .venv/bin/activate
25+
source .venv/bin/activate
2626
```
2727

2828
Make sure your editor is using the correct Python virtual environment, with the interpreter at `backend/.venv/bin/python`.
@@ -35,6 +35,12 @@ There are already configurations in place to run the backend through the VS Code
3535

3636
The setup is also already configured so you can run the tests through the VS Code Python tests tab.
3737

38+
Copy the `.vscode/settings.example.json` for convenience:
39+
40+
```console
41+
cp .vscode/settings.example.json .vscode/settings.json
42+
```
43+
3844
## Docker Compose Override
3945

4046
During development, you can change Docker Compose settings that will only affect the local development environment in the file `docker-compose.override.yml`.
@@ -46,21 +52,21 @@ For example, the directory with the backend code is synchronized in the Docker c
4652
There is also a command override that runs `fastapi run --reload` instead of the default `fastapi run`. It starts a single server process (instead of multiple, as would be for production) and reloads the process whenever the code changes. Have in mind that if you have a syntax error and save the Python file, it will break and exit, and the container will stop. After that, you can restart the container by fixing the error and running again:
4753

4854
```console
49-
$ docker compose watch
55+
docker compose watch
5056
```
5157

5258
There is also a commented out `command` override, you can uncomment it and comment the default one. It makes the backend container run a process that does "nothing", but keeps the container alive. That allows you to get inside your running container and execute commands inside, for example a Python interpreter to test installed dependencies, or start the development server that reloads when it detects changes.
5359

5460
To get inside the container with a `bash` session you can start the stack with:
5561

5662
```console
57-
$ docker compose watch
63+
docker compose watch
5864
```
5965

6066
and then in another terminal, `exec` inside the running container:
6167

6268
```console
63-
$ docker compose exec backend bash
69+
docker compose exec backend bash
6470
```
6571

6672
You should see an output like:
@@ -74,7 +80,7 @@ that means that you are in a `bash` session inside your container, as a `root` u
7480
There you can use the `fastapi run --reload` command to run the debug live reloading server.
7581

7682
```console
77-
$ fastapi run --reload app/main.py
83+
fastapi run --reload app/main.py
7884
```
7985

8086
...it will look like:
@@ -94,7 +100,7 @@ Nevertheless, if it doesn't detect a change but a syntax error, it will just sto
94100
To test the backend run:
95101

96102
```console
97-
$ bash ./scripts/test.sh
103+
bash ./scripts/test.sh
98104
```
99105

100106
The tests run with Pytest, modify and add tests to `./backend/app/tests/`.
@@ -130,23 +136,23 @@ Make sure you create a "revision" of your models and that you "upgrade" your dat
130136
* Start an interactive session in the backend container:
131137

132138
```console
133-
$ docker compose exec backend bash
139+
docker compose exec backend bash
134140
```
135141

136142
* Alembic is already configured to import your SQLModel models from `./backend/app/models.py`.
137143

138144
* After changing a model (for example, adding a column), inside the container, create a revision, e.g.:
139145

140146
```console
141-
$ alembic revision --autogenerate -m "Add column last_name to User model"
147+
alembic revision --autogenerate -m "Add column last_name to User model"
142148
```
143149

144150
* Commit to the git repository the files generated in the alembic directory.
145151

146152
* After creating the revision, run the migration in the database (this is what will actually change the database):
147153

148154
```console
149-
$ alembic upgrade head
155+
alembic upgrade head
150156
```
151157

152158
If you don't want to use migrations at all, uncomment the lines in the file at `./backend/app/core/db.py` that end in:
@@ -158,7 +164,7 @@ SQLModel.metadata.create_all(engine)
158164
and comment the line in the file `scripts/prestart.sh` that contains:
159165

160166
```console
161-
$ alembic upgrade head
167+
alembic upgrade head
162168
```
163169

164170
If you don't want to start with the default models and want to remove them / modify them, from the beginning, without having any previous revision, you can remove the revision files (`.py` Python files) under `./backend/app/alembic/versions/`. And then create a first migration as described above.

backend/app/api/deps.py

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Annotated
33

44
import jwt
5-
from fastapi import Depends, HTTPException, status
5+
from fastapi import Depends, HTTPException, Request, status
66
from fastapi.security import OAuth2PasswordBearer
77
from jwt.exceptions import InvalidTokenError
88
from pydantic import ValidationError
@@ -12,18 +12,27 @@
1212
from app.core.config import settings
1313
from app.core.db import engine
1414
from app.models import TokenPayload, User
15+
from app.repositories.items import ItemRepository
16+
from app.repositories.users import UserRepository
17+
from app.services.items import ItemService
18+
from app.services.users import UserService
1519

1620
reusable_oauth2 = OAuth2PasswordBearer(
1721
tokenUrl=f"{settings.API_V1_STR}/login/access-token"
1822
)
1923

2024

21-
def get_db() -> Generator[Session, None, None]:
22-
with Session(engine) as session:
23-
yield session
25+
def get_session(request: Request) -> Generator[Session, None, None]:
26+
"""reuses the session if it already exists in the request/response cycle"""
27+
request_db_session = getattr(request.state, "db_session", None)
28+
if request_db_session and isinstance(request_db_session, Session):
29+
yield request_db_session
30+
else:
31+
with Session(engine) as session:
32+
yield session
2433

2534

26-
SessionDep = Annotated[Session, Depends(get_db)]
35+
SessionDep = Annotated[Session, Depends(get_session)]
2736
TokenDep = Annotated[str, Depends(reusable_oauth2)]
2837

2938

@@ -55,3 +64,34 @@ def get_current_active_superuser(current_user: CurrentUser) -> User:
5564
status_code=403, detail="The user doesn't have enough privileges"
5665
)
5766
return current_user
67+
68+
69+
## Entities
70+
71+
72+
def user_repository(session: SessionDep) -> UserRepository:
73+
return UserRepository(session)
74+
75+
76+
UserRepositoryDep = Annotated[UserRepository, Depends(user_repository)]
77+
78+
79+
def user_service(user_repository: UserRepositoryDep) -> UserService:
80+
return UserService(user_repository)
81+
82+
83+
UserServiceDep = Annotated[UserService, Depends(user_service)]
84+
85+
86+
def item_repository(session: SessionDep) -> ItemRepository:
87+
return ItemRepository(session)
88+
89+
90+
ItemRepositoryDep = Annotated[ItemRepository, Depends(item_repository)]
91+
92+
93+
def item_service(item_repository: ItemRepositoryDep) -> ItemService:
94+
return ItemService(item_repository)
95+
96+
97+
ItemServiceDep = Annotated[ItemService, Depends(item_service)]

0 commit comments

Comments
 (0)