Skip to content

Commit bb07bd2

Browse files
committed
initialize backend
1 parent 46a24df commit bb07bd2

33 files changed

+1771
-15
lines changed

.editorconfig

Lines changed: 0 additions & 12 deletions
This file was deleted.

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# [helpwave tasks](https://helpwave.de/product/tasks)
22

3-
**helpwave tasks** is a modern, open-source task and ward-management platform tailored for healthcare designed to bring clarity, efficiency and structure to hospitals, wards and clinical workflows.
3+
**helpwave tasks** is a modern, open-source task and ward-management platform tailored for healthcare - designed to bring clarity, efficiency and structure to hospitals, wards and clinical workflows.
44

55
---
66

77
## 🚀 Quick Start
8-
WIP

backend/.gitignore

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.pyo
6+
*.pyd
7+
*.pyc
8+
9+
# Environment / virtualenv
10+
.env
11+
.venv/
12+
venv/
13+
env/
14+
ENV/
15+
16+
# IDEs / editors
17+
.vscode/
18+
.idea/
19+
*.sublime-project
20+
*.sublime-workspace
21+
22+
# Byte-compiled / cache
23+
*.log
24+
*.sqlite3
25+
*.db
26+
*.bak
27+
28+
# Migrations (optional: you may want to track Alembic migrations)
29+
app/db/migrations/__pycache__/
30+
app/db/migrations/versions/__pycache__/
31+
32+
# Redis / celery / temp files
33+
*.pid
34+
*.sock
35+
36+
# OS files
37+
.DS_Store
38+
Thumbs.db
39+
40+
# Coverage / test reports
41+
htmlcov/
42+
.coverage
43+
.tox/
44+
.pytest_cache/
45+
46+
# Logs
47+
logs/
48+
*.log
49+
50+
# Build / packaging
51+
build/
52+
dist/
53+
*.egg-info/
54+
55+
# Secrets (never commit)
56+
.env.local
57+
.env.*.local
58+
.env

backend/.gitkeep

Whitespace-only changes.

backend/Dockerfile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
ARG PY_VERSION="3.13"
2+
3+
FROM python:${PY_VERSION}-alpine AS builder
4+
5+
ENV PIP_NO_WARN_ABOUT_ROOT_USER=1
6+
7+
WORKDIR /build
8+
9+
RUN apk update && apk upgrade --no-cache && apk add gcc musl-dev libffi-dev libressl-dev && apk add gcc musl-dev libffi-dev libressl-dev
10+
11+
COPY requirements.txt /build
12+
13+
RUN pip install --prefix=/build/venv --no-cache-dir --upgrade -r requirements.txt
14+
15+
16+
FROM python:${PY_VERSION}-alpine
17+
18+
ENV PYTHONDONTWRITEBYTECODE=1
19+
ENV PYTHONUNBUFFERED=1
20+
21+
ENV PORT=80
22+
ENV HOST="0.0.0.0"
23+
24+
RUN apk update && apk upgrade --no-cache
25+
26+
COPY --from=builder /build/venv /usr/local/
27+
COPY . /app
28+
29+
WORKDIR /app
30+
31+
CMD ["sh", "-c", "alembic upgrade head && uvicorn main:app --proxy-headers --host $HOST --port $PORT"]

backend/alembic.ini

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# A generic, single database configuration.
2+
3+
[alembic]
4+
# path to migration scripts
5+
script_location = database/migrations
6+
7+
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
8+
# Uncomment the line below if you want the files to be prepended with date and time
9+
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
10+
11+
# sys.path path, will be prepended to sys.path if present.
12+
# defaults to the current working directory.
13+
prepend_sys_path = .
14+
15+
# timezone to use when rendering the date within the migration file
16+
# as well as the filename.
17+
# If specified, requires the python-dateutil library that can be installed by
18+
# adding `alembic[timezone]` to the pip install command.
19+
# string value is passed to dateutil.tz.gettz()
20+
# leave blank for localtime
21+
# timezone =
22+
23+
# max_overflow and pool_size for the SQLAlchemy engine
24+
# sqlalchemy.pool_size = 5
25+
# sqlalchemy.pool_max_overflow = 10
26+
27+
[loggers]
28+
keys = root,sqlalchemy,alembic
29+
30+
[handlers]
31+
keys = console
32+
33+
[formatters]
34+
keys = generic
35+
36+
[logger_root]
37+
level = WARN
38+
handlers = console
39+
qualname =
40+
41+
[logger_sqlalchemy]
42+
level = WARN
43+
handlers =
44+
qualname = sqlalchemy.engine
45+
46+
[logger_alembic]
47+
level = INFO
48+
handlers =
49+
qualname = alembic
50+
51+
[handler_console]
52+
class = StreamHandler
53+
args = (sys.stderr,)
54+
level = NOTSET
55+
formatter = generic
56+
57+
[formatter_generic]
58+
format = %(levelname)-5.5s [%(name)s] %(message)s
59+
datefmt = %H:%M:%S

backend/api/context.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from typing import Any
2+
3+
import strawberry
4+
from sqlalchemy.ext.asyncio import AsyncSession
5+
from strawberry.fastapi import BaseContext
6+
7+
8+
class Context(BaseContext):
9+
def __init__(self, db: AsyncSession):
10+
super().__init__()
11+
self.db = db
12+
13+
14+
async def get_context(db: AsyncSession) -> Context:
15+
return Context(db=db)
16+
17+
18+
Info = strawberry.Info[Context, Any]

backend/api/inputs.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from datetime import date, datetime
2+
from enum import Enum
3+
4+
import strawberry
5+
6+
7+
@strawberry.enum
8+
class Gender(Enum):
9+
MALE = "MALE"
10+
FEMALE = "FEMALE"
11+
UNKNOWN = "UNKNOWN"
12+
13+
14+
@strawberry.enum
15+
class LocationType(Enum):
16+
CLINIC = "CLINIC"
17+
TEAM = "TEAM"
18+
WARD = "WARD"
19+
ROOM = "ROOM"
20+
BED = "BED"
21+
OTHER = "OTHER"
22+
23+
24+
@strawberry.enum
25+
class FieldType(Enum):
26+
FIELD_TYPE_UNSPECIFIED = "FIELD_TYPE_UNSPECIFIED"
27+
FIELD_TYPE_TEXT = "FIELD_TYPE_TEXT"
28+
FIELD_TYPE_NUMBER = "FIELD_TYPE_NUMBER"
29+
FIELD_TYPE_CHECKBOX = "FIELD_TYPE_CHECKBOX"
30+
FIELD_TYPE_DATE = "FIELD_TYPE_DATE"
31+
FIELD_TYPE_DATE_TIME = "FIELD_TYPE_DATE_TIME"
32+
FIELD_TYPE_SELECT = "FIELD_TYPE_SELECT"
33+
FIELD_TYPE_MULTI_SELECT = "FIELD_TYPE_MULTI_SELECT"
34+
35+
36+
@strawberry.enum
37+
class PropertyEntity(Enum):
38+
PATIENT = "PATIENT"
39+
TASK = "TASK"
40+
41+
42+
@strawberry.input
43+
class PropertyValueInput:
44+
definition_id: strawberry.ID
45+
text_value: str | None = None
46+
number_value: float | None = None
47+
boolean_value: bool | None = None
48+
date_value: date | None = None
49+
date_time_value: datetime | None = None
50+
select_value: str | None = None
51+
multi_select_values: list[str] | None = None
52+
53+
54+
@strawberry.input
55+
class CreatePatientInput:
56+
firstname: str
57+
lastname: str
58+
birthdate: date
59+
gender: Gender
60+
assigned_location_id: strawberry.ID | None = None
61+
properties: list[PropertyValueInput] | None = None
62+
63+
64+
@strawberry.input
65+
class UpdatePatientInput:
66+
firstname: str | None = None
67+
lastname: str | None = None
68+
birthdate: date | None = None
69+
gender: Gender | None = None
70+
assigned_location_id: strawberry.ID | None = None
71+
properties: list[PropertyValueInput] | None = None
72+
73+
74+
@strawberry.input
75+
class CreateTaskInput:
76+
title: str
77+
patient_id: strawberry.ID
78+
description: str | None = None
79+
assignee_id: strawberry.ID | None = None
80+
previous_task_ids: list[strawberry.ID] | None = None
81+
properties: list[PropertyValueInput] | None = None
82+
83+
84+
@strawberry.input
85+
class UpdateTaskInput:
86+
title: str | None = None
87+
description: str | None = None
88+
done: bool | None = None
89+
assignee_id: strawberry.ID | None = None
90+
previous_task_ids: list[strawberry.ID] | None = None
91+
properties: list[PropertyValueInput] | None = None
92+
93+
94+
@strawberry.input
95+
class CreateLocationNodeInput:
96+
title: str
97+
kind: LocationType
98+
parent_id: strawberry.ID | None = None
99+
100+
101+
@strawberry.input
102+
class UpdateLocationNodeInput:
103+
title: str | None = None
104+
kind: LocationType | None = None
105+
parent_id: strawberry.ID | None = None
106+
107+
108+
@strawberry.input
109+
class CreatePropertyDefinitionInput:
110+
name: str
111+
field_type: FieldType
112+
allowed_entities: list[PropertyEntity]
113+
description: str | None = None
114+
options: list[str] | None = None
115+
is_active: bool = True
116+
117+
118+
@strawberry.input
119+
class UpdatePropertyDefinitionInput:
120+
name: str | None = None
121+
description: str | None = None
122+
options: list[str] | None = None
123+
is_active: bool | None = None
124+
allowed_entities: list[PropertyEntity] | None = None

0 commit comments

Comments
 (0)