Merge branch 'main' into merge/frontend_basics

This commit is contained in:
2025-10-21 13:31:50 +02:00
committed by GitHub
22 changed files with 508 additions and 425 deletions

View File

@@ -14,6 +14,16 @@ from app.api.categories import router as categories_router
from app.api.transactions import router as transactions_router
from app.services.user_service import auth_backend, current_active_verified_user, fastapi_users, get_oauth_provider
from fastapi import FastAPI
import sentry_sdk
sentry_sdk.init(
dsn=os.getenv("SENTRY_DSN"),
send_default_pii=True,
)
app = FastAPI()
fastApi = FastAPI()
# CORS for frontend dev server
@@ -86,3 +96,7 @@ async def root():
@fastApi.get("/authenticated-route")
async def authenticated_route(user: User = Depends(current_active_verified_user)):
return {"message": f"Hello {user.email}!"}
@fastApi.get("/sentry-debug")
async def trigger_error():
division_by_zero = 1 / 0

View File

@@ -50,6 +50,7 @@ python-dateutil==2.9.0.post0
python-dotenv==1.1.1
python-multipart==0.0.20
PyYAML==6.0.2
sentry-sdk==2.42.0
six==1.17.0
sniffio==1.3.1
SQLAlchemy==2.0.43
@@ -58,6 +59,7 @@ tomli==2.2.1
typing-inspection==0.4.1
typing_extensions==4.15.0
tzdata==2025.2
urllib3==2.5.0
uvicorn==0.37.0
uvloop==0.21.0
vine==5.1.0

View File

@@ -1,54 +0,0 @@
Thank you for installing myapp-chart.
This chart packages all Kubernetes manifests from the original deployment directory and parameterizes environment, database name (with optional PR suffix), image, and domain for external access.
Namespaces per developer (important):
- Install each developer's environment into their own namespace using Helm's -n/--namespace flag.
- No hardcoded namespace is used in templates; resources are created in .Release.Namespace.
- Example namespaces: dev-alice, dev-bob, pr-123, etc.
Key values:
- deployment -> used as Database CR name and DB username (MARIADB_DB and MARIADB_USER)
- image.repository/tag or image.digest -> container image
- domain -> public FQDN used by TunnelBinding (required to expose app)
- app/worker names, replicas, ports
Examples:
- Dev install (Alice):
helm upgrade --install myapp ./7project/charts/myapp-chart \
-n dev-alice --create-namespace \
-f values-dev.yaml \
--set domain=alice.demo.example.com \
--set-string rabbitmq.password="$RABBITMQ_PASSWORD" \
--set-string database.password="$DB_PASSWORD"
- Dev install (Bob):
helm upgrade --install myapp ./7project/charts/myapp-chart \
-n dev-bob --create-namespace \
-f values-dev.yaml \
--set domain=bob.demo.example.com
- Prod install (different cleanupPolicy):
helm upgrade --install myapp ./7project/charts/myapp-chart \
-n prod --create-namespace \
-f values-prod.yaml \
--set domain=app.example.com
- PR (preview) install with DB name containing PR number (also its own namespace):
PR=123
helm upgrade --install myapp-pr-$PR ./7project/charts/myapp-chart \
-n pr-$PR --create-namespace \
-f values-dev.yaml \
--set prNumber=$PR \
--set deployment=preview-$PR \
--set domain=pr-$PR.example.com
- Use a custom deployment identifier to suffix DB name, DB username and Secret name:
helm upgrade --install myapp ./7project/charts/myapp-chart \
-n dev-alice --create-namespace \
-f values-dev.yaml \
--set deployment=alice \
--set domain=alice.demo.example.com
Render locally (dry run):
helm template ./7project/charts/myapp-chart -f values-dev.yaml --set prNumber=456 --set deployment=test --set domain=demo.example.com --namespace dev-test | sed -n '/kind: Database/,$p' | head -n 30

View File

@@ -20,7 +20,7 @@ spec:
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
drop: [ "ALL" ]
ports:
- containerPort: {{ .Values.app.port }}
env:
@@ -29,21 +29,27 @@ spec:
- name: MARIADB_PORT
value: '3306'
- name: MARIADB_DB
value: {{ required "Set .Values.deployment" .Values.deployment | quote }}
valueFrom:
secretKeyRef:
name: prod
key: MARIADB_DB
- name: MARIADB_USER
value: {{ required "Set .Values.deployment" .Values.deployment | quote }}
valueFrom:
secretKeyRef:
name: prod
key: MARIADB_USER
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ required "Set .Values.database.secretName" .Values.database.secretName }}
key: password
name: prod
key: MARIADB_PASSWORD
- name: RABBITMQ_USERNAME
value: {{ .Values.rabbitmq.username | quote }}
- name: RABBITMQ_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-user-credentials" (.Values.rabbitmq.username | default "app-user") }}
key: password
name: prod
key: RABBITMQ_PASSWORD
- name: RABBITMQ_HOST
value: {{ printf "%s.%s.svc.cluster.local" "rabbitmq-cluster" .Release.Namespace | quote }}
- name: RABBITMQ_PORT
@@ -52,6 +58,39 @@ spec:
value: {{ .Values.rabbitmq.vhost | default "/" | quote }}
- name: MAIL_QUEUE
value: {{ .Values.worker.mailQueueName | default "mail_queue" | quote }}
- name: MOJEID_CLIENT_ID
valueFrom:
secretKeyRef:
name: prod
key: MOJEID_CLIENT_ID
- name: MOJEID_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: prod
key: MOJEID_CLIENT_SECRET
- name: BANKID_CLIENT_ID
valueFrom:
secretKeyRef:
name: prod
key: BANKID_CLIENT_ID
- name: BANKID_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: prod
key: BANKID_CLIENT_SECRET
- name: DOMAIN
value: {{ required "Set .Values.domain" .Values.domain | quote }}
- name: DOMAIN_SCHEME
value: {{ required "Set .Values.domain_scheme" .Values.domain_scheme | quote }}
- name: FRONTEND_DOMAIN
value: {{ required "Set .Values.frontend_domain" .Values.frontend_domain | quote }}
- name: FRONTEND_DOMAIN_SCHEME
value: {{ required "Set .Values.frontend_domain_scheme" .Values.frontend_domain_scheme | quote }}
- name: SENTRY_DSN
valueFrom:
secretKeyRef:
name: prod
key: SENTRY_DSN
livenessProbe:
httpGet:
path: /

View File

@@ -0,0 +1,18 @@
apiVersion: v1
kind: Secret
metadata:
name: prod
type: Opaque
stringData:
MOJEID_CLIENT_ID: {{ .Values.oauth.mojeid.clientId | quote }}
MOJEID_CLIENT_SECRET: {{ .Values.oauth.mojeid.clientSecret | quote }}
BANKID_CLIENT_ID: {{ .Values.oauth.bankid.clientId | quote }}
BANKID_CLIENT_SECRET: {{ .Values.oauth.bankid.clientSecret | quote }}
# Database credentials
MARIADB_DB: {{ required "Set .Values.deployment" .Values.deployment | quote }}
MARIADB_USER: {{ required "Set .Values.deployment" .Values.deployment | quote }}
MARIADB_PASSWORD: {{ .Values.database.password | default "" | quote }}
# RabbitMQ credentials
RABBITMQ_PASSWORD: {{ .Values.rabbitmq.password | default "" | quote }}
RABBITMQ_USERNAME: {{ .Values.rabbitmq.username | quote }}
SENTRY_DSN: {{ .Values.sentry_dsn | quote }}

View File

@@ -31,13 +31,32 @@ spec:
- --loglevel
- INFO
env:
- name: MARIADB_HOST
value: "mariadb-repl-maxscale-internal.mariadb-operator.svc.cluster.local"
- name: MARIADB_PORT
value: '3306'
- name: MARIADB_DB
valueFrom:
secretKeyRef:
name: prod
key: MARIADB_DB
- name: MARIADB_USER
valueFrom:
secretKeyRef:
name: prod
key: MARIADB_USER
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: prod
key: MARIADB_PASSWORD
- name: RABBITMQ_USERNAME
value: {{ .Values.rabbitmq.username | quote }}
- name: RABBITMQ_PASSWORD
valueFrom:
secretKeyRef:
name: {{ printf "%s-user-credentials" (.Values.rabbitmq.username | default "app-user") }}
key: password
name: prod
key: RABBITMQ_PASSWORD
- name: RABBITMQ_HOST
value: {{ printf "%s.%s.svc.cluster.local" "rabbitmq-cluster" .Release.Namespace | quote }}
- name: RABBITMQ_PORT
@@ -46,3 +65,8 @@ spec:
value: {{ .Values.rabbitmq.vhost | default "/" | quote }}
- name: MAIL_QUEUE
value: {{ .Values.worker.mailQueueName | default "mail_queue" | quote }}
- name: SENTRY_DSN
valueFrom:
secretKeyRef:
name: prod
key: SENTRY_DSN

View File

@@ -11,6 +11,12 @@ deployment: ""
# Public domain to expose the app under (used by TunnelBinding fqdn)
# Set at install time: --set domain=example.com
domain: ""
domain_scheme: ""
frontend_domain: ""
frontend_domain_scheme: ""
sentry_dsn: ""
image:
repository: lukastrkan/cc-app-demo
@@ -33,6 +39,14 @@ worker:
service:
port: 80
oauth:
bankid:
clientId: ""
clientSecret: ""
mojeid:
clientId: ""
clientSecret: ""
rabbitmq:
create: true
replicas: 1

View File

@@ -1,20 +0,0 @@
apiVersion: k8s.mariadb.com/v1alpha1
kind: Grant
metadata:
name: grant
spec:
mariaDbRef:
name: mariadb-repl
namespace: mariadb-operator
privileges:
- "ALL PRIVILEGES"
database: "app-demo-database"
table: "*"
username: "app-demo-user"
grantOption: true
host: "%"
# Delete the resource in the database whenever the CR gets deleted.
# Alternatively, you can specify Skip in order to omit deletion.
cleanupPolicy: Skip
requeueInterval: 10h
retryInterval: 30s

View File

@@ -1,7 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: app-demo-database-secret
type: kubernetes.io/basic-auth
stringData:
password: "strongpassword"

View File

@@ -1,20 +0,0 @@
apiVersion: k8s.mariadb.com/v1alpha1
kind: User
metadata:
name: app-demo-user
spec:
# If you want the user to be created with a different name than the resource name
# name: user-custom
mariaDbRef:
name: mariadb-repl
namespace: mariadb-operator
passwordSecretKeyRef:
name: app-demo-database-secret
key: password
maxUserConnections: 20
host: "%"
# Delete the resource in the database whenever the CR gets deleted.
# Alternatively, you can specify Skip in order to omit deletion.
cleanupPolicy: Skip
requeueInterval: 10h
retryInterval: 30s

View File

@@ -1,15 +0,0 @@
apiVersion: k8s.mariadb.com/v1alpha1
kind: Database
metadata:
name: app-demo-database
spec:
mariaDbRef:
name: mariadb-repl
namespace: mariadb-operator
characterSet: utf8
collate: utf8_general_ci
# Delete the resource in the database whenever the CR gets deleted.
# Alternatively, you can specify Skip in order to omit deletion.
cleanupPolicy: Skip
requeueInterval: 10h
retryInterval: 30s

View File

@@ -1,48 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-demo
spec:
replicas: 3
revisionHistoryLimit: 3
selector:
matchLabels:
app: app-demo
template:
metadata:
labels:
app: app-demo
spec:
containers:
- image: lukastrkan/cc-app-demo@sha256:75634b4d97282b6b8424fe17767c81adf44af5f7359c1d25883073b5629b3e05
name: app-demo
ports:
- containerPort: 8000
env:
- name: MARIADB_HOST
value: mariadb-repl.mariadb-operator.svc.cluster.local
- name: MARIADB_PORT
value: '3306'
- name: MARIADB_DB
value: app-demo-database
- name: MARIADB_USER
value: app-demo-user
- name: MARIADB_PASSWORD
valueFrom:
secretKeyRef:
name: app-demo-database-secret
key: password
livenessProbe:
httpGet:
path: /
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /
port: 8000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3

View File

@@ -1,10 +0,0 @@
apiVersion: v1
kind: Service
metadata:
name: app-demo
spec:
ports:
- port: 80
targetPort: 8000
selector:
app: app-demo

View File

@@ -1,41 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-demo-worker
spec:
replicas: 3
revisionHistoryLimit: 3
selector:
matchLabels:
app: app-demo-worker
template:
metadata:
labels:
app: app-demo-worker
spec:
containers:
- image: lukastrkan/cc-app-demo@sha256:75634b4d97282b6b8424fe17767c81adf44af5f7359c1d25883073b5629b3e05
name: app-demo-worker
command:
- celery
- -A
- app.celery_app
- worker
- -Q
- $(MAIL_QUEUE)
- --loglevel
- INFO
env:
- name: RABBITMQ_USERNAME
value: demo-app
- name: RABBITMQ_PASSWORD
valueFrom:
secretKeyRef:
name: demo-app-user-credentials
key: password
- name: RABBITMQ_HOST
value: rabbitmq.rabbitmq.svc.cluster.local
- name: RABBITMQ_PORT
value: '5672'
- name: RABBITMQ_VHOST
value: "/"

View File

@@ -1,14 +0,0 @@
apiVersion: networking.cfargotunnel.com/v1alpha1
kind: TunnelBinding
metadata:
name: guestbook-tunnel-binding
namespace: group-project
subjects:
- name: app-server
spec:
target: http://app-demo.group-project.svc.cluster.local
fqdn: demo.ltrk.cz
noTlsVerify: true
tunnelRef:
kind: ClusterTunnel
name: cluster-tunnel

View File

@@ -0,0 +1,53 @@
# Weekly Meeting Notes
- Group 8 - Personal finance tracker
- Mentor: Jaychander
Keep all meeting notes in the `meetings.md` file in your project folder.
Just copy the template below for each weekly meeting and fill in the details.
## Administrative Info
- Date: 2025-10-08
- Attendees: Dejan Ribarovski, Lukas Trkan
- Notetaker: Dejan Ribarovski
## Progress Update (Before Meeting)
Summary of what has been accomplished since the last meeting in the following categories.
## Action Items from Last Week (During Meeting)
- [x] start coding the app logic
- [x] start writing the report so it matches the actual progress
- [x] redo the system diagram so it includes a response flow
### Coding
Implemented initial functioning version of the app, added OAuth with BankId and MojeID,
added database snapshots.
### Documentation
report.md is up to date
## Questions and Topics for Discussion (Before Meeting)
Prepare 3-5 questions and topics you want to discuss with your mentor.
1. What other functionality should be added to the app
2. Priority for the next week (Testing maybe?)
3. Question 3
## Discussion Notes (During Meeting)
## Action Items for Next Week (During Meeting)
Last 3 minutes of the meeting, summarize action items.
- [ ] OAuth
- [ ] CI/CD fix
- [ ] Database local (multiple bank accounts)
- [ ] Add tests and set up github pipeline
- [ ] Frontend imporvment - user experience
- [ ] make the report more clear
---

View File

@@ -1,4 +1,4 @@
# Project Report
# Personal finance tracker
> **Instructions**:
> This template provides the structure for your project report.
@@ -7,126 +7,211 @@
## Project Overview
**Project Name**: [Your project name]
**Project Name**: Personal Finance Tracker
**Group Members**:
- Student number, Name, GitHub username
- Student number, Name, GitHub username
- Student number, Name, GitHub username
- 289229, Lukáš Trkan, lukastrkan
- 289258, Dejan Ribarovski, derib2613, ribardej
**Brief Description**:
[2-3 sentences describing what your application does and its main purpose]
Our application is a finance tracker, so a person can easily track his cash flow
through multiple bank accounts. Person can label transactions with custom categories
and later filter by them.
## Architecture Overview
Our system is a fullstack web application composed of a React frontend, a FastAPI backend, a PostgreSQL database, and asynchronous background workers powered by Celery with RabbitMQ. Redis is available for caching/kv and may be used by Celery as a result backend. The backend exposes REST endpoints for authentication (email/password and OAuth), users, categories, and transactions. A thin controller layer (FastAPI routers) lives under app/api. Infrastructure for Kubernetes is provided via OpenTofu (Terraformcompatible) modules and the application is packaged via a Helm chart.
### High-Level Architecture
[Describe the overall system architecture. Consider including a diagram using mermaid or linking to an image]
```mermaid
graph TD
A[Component A] --> B[Component B]
B --> C[Component C]
flowchart LR
proc_queue[Message Queue] --> proc_queue_worker[Worker Service]
proc_queue_worker --> ext_mail[(Email Service)]
proc_cron[Task planner] --> proc_queue
proc_queue_worker --> ext_bank[(Bank API)]
proc_queue_worker --> db
client[Client/Frontend] <--> svc[Backend API]
svc --> proc_queue
svc <--> db[(Database)]
svc <--> cache[(Cache)]
```
### Components
- **Component 1**: [Description of what this component does]
- **Component 2**: [Description of what this component does]
- **Component 3**: [Description of what this component does]
- Frontend (frontend/): React + TypeScript app built with Vite. Talks to the backend via REST, handles login/registration, shows latest transactions, filtering, and allows adding transactions.
- Backend API (backend/app): FastAPI app with routers under app/api for auth, categories, and transactions. Uses FastAPI Users for auth (JWT + OAuth), SQLAlchemy ORM, and Pydantic v2 schemas.
- Worker service (backend/app/workers): Celery worker handling asynchronous tasks (e.g., sending verification emails, future background processing).
- Database (PostgreSQL): Persists users, categories, transactions; schema managed by Alembic migrations.
- Message Queue (RabbitMQ): Transports background jobs from the API to the worker.
- Cache/Result Store (Redis): Available for caching or Celery result backend.
- Infrastructure as Code (tofu/): OpenTofu modules provisioning cluster services (RabbitMQ, Redis, Argo CD, cert-manager, Cloudflare tunnel, etc.).
- Deployment Chart (charts/myapp-chart/): Helm chart to deploy the application to Kubernetes.
### Technologies Used
- **Backend**: [e.g., Go, Node.js, Python]
- **Database**: [e.g., PostgreSQL, MongoDB, Redis]
- **Cloud Services**: [e.g., AWS EC2, Google Cloud Run, Azure Functions]
- **Container Orchestration**: [e.g., Docker, Kubernetes]
- **Other**: [List other significant technologies]
- Backend: Python, FastAPI, FastAPI Users, SQLAlchemy, Pydantic, Alembic, Celery
- Frontend: React, TypeScript, Vite
- Database: PostgreSQL
- Messaging: RabbitMQ
- Cache: Redis
- Containerization/Orchestration: Docker, Docker Compose (dev), Kubernetes, Helm
- IaC/Platform: OpenTofu (Terraform), Argo CD, cert-manager, MetalLB, Cloudflare Tunnel, Prometheus
## Prerequisites
### System Requirements
- Operating System: [e.g., Linux, macOS, Windows]
- Minimum RAM: [e.g., 8GB]
- Storage: [e.g., 10GB free space]
- Operating System: Linux, macOS, or Windows
- Minimum RAM: 4 GB (8 GB recommended for running backend, frontend, and database together)
- Storage: 2 GB free (Docker images may require additional space)
### Required Software
- [Software 1] (version X.X or higher)
- [Software 2] (version X.X or higher)
- [etc.]
- Docker Desktop or Docker Engine 24+
- Docker Compose v2+
- Node.js 20+ and npm 10+ (for local frontend dev/build)
- Python 3.12+ (for local backend dev outside Docker)
- PostgreSQL 15+ (optional if running DB outside Docker)
- Helm 3.12+ and kubectl 1.29+ (for Kubernetes deployment)
- OpenTofu 1.7+ (for infrastructure provisioning)
### Dependencies
### Environment Variables (common)
```bash
# List key dependencies that need to be installed
# For example:
# Docker Engine 20.10+
# Node.js 18+
# Go 1.25+
```
- Backend: SECRET, FRONTEND_URL, BACKEND_URL, DATABASE_URL, RABBITMQ_URL, REDIS_URL
- OAuth vars (Backend): MOJEID_CLIENT_ID/SECRET, BANKID_CLIENT_ID/SECRET (optional)
- Frontend: VITE_BACKEND_URL
### Dependencies (key libraries)
I am not sure what is meant by "key libraries"
Backend: FastAPI, fastapi-users, SQLAlchemy, pydantic v2, Alembic, Celery
Frontend: React, TypeScript, Vite
Services: PostgreSQL, RabbitMQ, Redis
## Build Instructions
### 1. Clone the Repository
You can run the project with Docker Compose (recommended for local development) or run services manually.
### 1) Clone the Repository
```bash
git clone [your-repository-url]
cd [repository-name]
git clone https://github.com/dat515-2025/Group-8.git
cd 7project
```
### 2. Install Dependencies
### 2) Install dependencies
Backend
```bash
# Provide step-by-step commands
# For example:
# npm install
# go mod download
# In 7project/backend
python3.12 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
```
### 3. Build the Application
Frontend
```bash
# Provide exact build commands
# For example:
# make build
# docker build -t myapp .
# In 7project/frontend
npm install
```
### 4. Configuration
### 3) Manual Local Run
Backend
```bash
# Any configuration steps needed
# Environment variables to set
# Configuration files to create
# From the 7project/ directory
docker compose up --build
# This starts: PostgreSQL, RabbitMQ/Redis (if defined)
# Set environment variables (or create .env file)
export SECRET=CHANGE_ME_SECRET
export BACKEND_URL=http://127.0.0.1:8000
export FRONTEND_URL=http://localhost:5173
export DATABASE_URL=postgresql+asyncpg://user:password@127.0.0.1:5432/app
export RABBITMQ_URL=amqp://guest:guest@127.0.0.1:5672/
export REDIS_URL=redis://127.0.0.1:6379/0
# Apply DB migrations (Alembic)
# From 7project/backend
alembic upgrade head
# Run API
uvicorn app.app:fastApi --reload --host 0.0.0.0 --port 8000
# Run Celery worker (optional, for emails/background tasks)
celery -A app.celery_app.celery_app worker -l info
```
Frontend
```bash
# Configure backend URL for dev
echo 'VITE_BACKEND_URL=http://127.0.0.1:8000' > .env
npm run dev
# Open http://localhost:5173
```
- Backend default: http://127.0.0.1:8000 (OpenAPI at /docs)
- Frontend default: http://localhost:5173
If needed, adjust compose services/ports in compose.yml.
## Deployment Instructions
### Local Deployment
### Local (Docker Compose)
Described in the previous section (Manual Local Run)
### Kubernetes (via OpenTofu + Helm)
1) Provision platform services (RabbitMQ/Redis/ingress/tunnel/etc.) with OpenTofu
```bash
# Step-by-step commands for local deployment
# For example:
# docker-compose up -d
# kubectl apply -f manifests/
cd tofu
# copy and edit variables
cp terraform.tfvars.example terraform.tfvars
# authenticate to your cluster/cloud as needed, then:
tofu init
tofu plan
tofu apply
```
### Cloud Deployment
2) Deploy the app using Helm
```bash
# Commands for cloud deployment
# Include any cloud-specific setup
# Set the namespace
kubectl create namespace myapp || true
# Install/upgrade the chart with required values
helm upgrade --install myapp charts/myapp-chart \
-n myapp \
-f charts/myapp-chart/values.yaml \
--set image.backend.repository=myorg/myapp-backend \
--set image.backend.tag=latest \
--set env.BACKEND_URL="https://myapp.example.com" \
--set env.FRONTEND_URL="https://myapp.example.com" \
--set env.SECRET="CHANGE_ME_SECRET"
```
Adjust values to your registry and domain. The charts NOTES.txt includes additional examples.
3) Expose and access
- If using Cloudflare Tunnel or an ingress, configure DNS accordingly (see tofu/modules/cloudflare and deployment/tunnel.yaml).
- For quick testing without ingress:
```bash
kubectl -n myapp port-forward deploy/myapp-backend 8000:8000
kubectl -n myapp port-forward deploy/myapp-frontend 5173:80
```
### Verification
```bash
# Commands to verify deployment worked
# How to check if services are running
# Example health check endpoints
# Check pods
kubectl -n myapp get pods
# Backend health
curl -i http://127.0.0.1:8000/
# OpenAPI
open http://127.0.0.1:8000/docs
# Frontend (if port-forwarded)
open http://localhost:5173
```
## Testing Instructions
@@ -156,19 +241,38 @@ cd [repository-name]
## Usage Examples
### Basic Usage
All endpoints are documented at OpenAPI: http://127.0.0.1:8000/docs
### Auth: Register and Login (JWT)
```bash
# Examples of how to use the application
# Common commands or API calls
# Sample data or test scenarios
# Register
curl -X POST http://127.0.0.1:8000/auth/register \
-H 'Content-Type: application/json' \
-d '{
"email": "user@example.com",
"password": "StrongPassw0rd",
"first_name": "Jane",
"last_name": "Doe"
}'
# Login (JWT)
TOKEN=$(curl -s -X POST http://127.0.0.1:8000/auth/jwt/login \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'username=user@example.com&password=StrongPassw0rd' | jq -r .access_token)
echo $TOKEN
# Call a protected route
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8000/authenticated-route
```
### Advanced Features
### Frontend
```bash
# Examples showcasing advanced functionality
```
- Start with: npm run dev in 7project/frontend
- Ensure VITE_BACKEND_URL is set to the backend URL (e.g., http://127.0.0.1:8000)
- Open http://localhost:5173
- Login, view latest transactions, filter, and add new transactions from the UI.
---
@@ -215,18 +319,18 @@ cd [repository-name]
> This information is used for individual grading.
> Link to the specific commit on GitHub for each contribution.
| Task/Component | Assigned To | Status | Time Spent | Difficulty | Notes |
| ------------------------------------------------------------------- | ----------- | ------------- | ---------- | ---------- | ----------- |
| Project Setup & Repository | [Name] | ✅ Complete | [X hours] | Medium | [Any notes] |
| [Design Document](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Easy | [Any notes] |
| [Backend API Development](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Hard | [Any notes] |
| [Database Setup & Models](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Medium | [Any notes] |
| [Frontend Development](https://github.com/dat515-2025/group-name) | [Name] | 🔄 In Progress | [X hours] | Medium | [Any notes] |
| [Docker Configuration](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Easy | [Any notes] |
| [Cloud Deployment](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Hard | [Any notes] |
| [Testing Implementation](https://github.com/dat515-2025/group-name) | [Name] | ⏳ Pending | [X hours] | Medium | [Any notes] |
| [Documentation](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Easy | [Any notes] |
| [Presentation Video](https://github.com/dat515-2025/group-name) | [Name] | ✅ Complete | [X hours] | Medium | [Any notes] |
| Task/Component | Assigned To | Status | Time Spent | Difficulty | Notes |
|-----------------------------------------------------------------------|-------------| ------------- |----------------|------------| ----------- |
| [Project Setup & Repository](https://github.com/dat515-2025/Group-8#) | Lukas | ✅ Complete | [X hours] | Medium | [Any notes] |
| [Design Document](https://github.com/dat515-2025/Group-8/blob/main/6design/design.md) | Both | ✅ Complete | 2 Hours | Easy | [Any notes] |
| [Backend API Development](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/api) | Dejan | ✅ Complete | 10 hours | Medium | [Any notes] |
| [Database Setup & Models](https://github.com/dat515-2025/Group-8/tree/main/7project/backend/app/models) | Lukas | ✅ Complete | [X hours] | Medium | [Any notes] |
| [Frontend Development](https://github.com/dat515-2025/Group-8/tree/main/7project/frontend) | Dejan | 🔄 In Progress | 7 hours so far | Medium | [Any notes] |
| [Docker Configuration](https://github.com/dat515-2025/Group-8/blob/main/7project/compose.yml) | Lukas | ✅ Complete | [X hours] | Easy | [Any notes] |
| [Cloud Deployment](https://github.com/dat515-2025/Group-8/blob/main/7project/deployment/app-demo-deployment.yaml) | Lukas | ✅ Complete | [X hours] | Hard | [Any notes] |
| [Testing Implementation](https://github.com/dat515-2025/group-name) | Dejan | ❌ Not Started | [X hours] | Medium | [Any notes] |
| [Documentation](https://github.com/dat515-2025/group-name) | Both | ❌ Not Started | [X hours] | Easy | [Any notes] |
| [Presentation Video](https://github.com/dat515-2025/group-name) | Both | ❌ Not Started | [X hours] | Medium | [Any notes] |
**Legend**: ✅ Complete | 🔄 In Progress | ⏳ Pending | ❌ Not Started
@@ -244,25 +348,16 @@ cd [repository-name]
| [Date] | Documentation | [X.X] | Updated README and design doc |
| **Total** | | **[XX.X]** | |
### [Team Member 2 Name]
### Dejan
| Date | Activity | Hours | Description |
| --------- | -------------------- | ---------- | ----------------------------------------- |
| [Date] | Frontend Development | [X.X] | Created user interface mockups |
| [Date] | Integration | [X.X] | Connected frontend to backend API |
| [Date] | Deployment | [X.X] | Docker configuration and cloud deployment |
| [Date] | Testing | [X.X] | End-to-end testing |
| **Total** | | **[XX.X]** | |
| Date | Activity | Hours | Description |
|-------------|----------------------|--------|--------------------------------|
| 25.9. | Design | 1.5 | 6design |
| 9-11.10. | Backend APIs | 10 | Implemented Backend APIs |
| 13-15.10. | Frontend Development | 6.5 | Created user interface mockups |
| Continually | Documantation | 3 | Documenting the dev process |
| **Total** | | **21** | |
### [Team Member 3 Name] (if applicable)
| Date | Activity | Hours | Description |
| --------- | ------------------------ | ---------- | -------------------------------- |
| [Date] | Database Design | [X.X] | Schema design and implementation |
| [Date] | Cloud Configuration | [X.X] | AWS/GCP setup and configuration |
| [Date] | Performance Optimization | [X.X] | Caching and query optimization |
| [Date] | Monitoring | [X.X] | Logging and monitoring setup |
| **Total** | | **[XX.X]** | |
### Group Total: [XXX.X] hours
@@ -292,11 +387,8 @@ cd [repository-name]
[Personal reflection on growth, challenges, and learning]
#### [Team Member 3 Name] (if applicable)
[Personal reflection on growth, challenges, and learning]
---
**Report Completion Date**: [Date]
**Last Updated**: [Date]
**Last Updated**: 15.10.2025