Skip to content
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.idea/
.DS_Store
.vscode/*
!.vscode/extensions.json
node_modules/
Expand Down
70 changes: 8 additions & 62 deletions compose.override.yml
Original file line number Diff line number Diff line change
@@ -1,59 +1,12 @@
services:

# Local services are available on their ports, but also available on:
# http://api.localhost.tiangolo.com: backend
# http://dashboard.localhost.tiangolo.com: frontend
# etc. To enable it, update .env, set:
# DOMAIN=localhost.tiangolo.com
proxy:
image: traefik:3.6
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "80:80"
- "8090:8080"
# Duplicate the command from compose.yml to add --api.insecure=true
command:
# Enable Docker in Traefik, so that it reads labels from Docker services
- --providers.docker
# Add a constraint to only use services with the label for this stack
- --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`)
# Do not expose all Docker services, only the ones explicitly exposed
- --providers.docker.exposedbydefault=false
# Create an entrypoint "http" listening on port 80
- --entrypoints.http.address=:80
# Create an entrypoint "https" listening on port 443
- --entrypoints.https.address=:443
# Enable the access log, with HTTP requests
- --accesslog
# Enable the Traefik log, for configurations and errors
- --log
# Enable debug logging for local development
- --log.level=DEBUG
# Enable the Dashboard and API
- --api
# Enable the Dashboard and API in insecure mode for local development
- --api.insecure=true
labels:
# Enable Traefik for this service, to make it available in the public network
- traefik.enable=true
- traefik.constraint-label=traefik-public
# Dummy https-redirect middleware that doesn't really redirect, only to
# allow running it locally
- traefik.http.middlewares.https-redirect.contenttype.autodetect=false
networks:
- traefik-public
- default

db:
restart: "no"
ports:
- "5432:5432"

adminer:
prestart:
restart: "no"
ports:
- "8080:8080"

backend:
restart: "no"
Expand All @@ -62,7 +15,6 @@ services:
build:
context: .
dockerfile: backend/Dockerfile
# command: sleep infinity # Infinite loop to keep container alive doing nothing
command:
- fastapi
- run
Expand All @@ -78,7 +30,6 @@ services:
- .venv
- path: ./backend/pyproject.toml
action: rebuild
# TODO: remove once coverage is done locally
volumes:
- ./backend/htmlcov:/app/backend/htmlcov
environment:
Expand All @@ -87,12 +38,6 @@ services:
SMTP_TLS: "false"
EMAILS_FROM_EMAIL: "noreply@example.com"

mailcatcher:
image: schickling/mailcatcher
ports:
- "1080:1080"
- "1025:1025"

frontend:
restart: "no"
ports:
Expand All @@ -101,9 +46,15 @@ services:
context: .
dockerfile: frontend/Dockerfile
args:
- VITE_API_URL=http://localhost:8000
- VITE_API_URL=
- NODE_ENV=development

mailcatcher:
image: schickling/mailcatcher
ports:
- "1080:1080"
- "1025:1025"

playwright:
build:
context: .
Expand All @@ -120,7 +71,6 @@ services:
environment:
- VITE_API_URL=http://backend:8000
- MAILCATCHER_HOST=http://mailcatcher:1080
# For the reports when run locally
- PLAYWRIGHT_HTML_HOST=0.0.0.0
- CI=${CI}
volumes:
Expand All @@ -129,7 +79,3 @@ services:
ports:
- 9323:9323

networks:
traefik-public:
# For local dev, don't expect an external Traefik network
external: false
95 changes: 8 additions & 87 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,11 @@ services:
- POSTGRES_USER=${POSTGRES_USER?Variable not set}
- POSTGRES_DB=${POSTGRES_DB?Variable not set}

adminer:
image: adminer
restart: always
networks:
- traefik-public
- default
depends_on:
- db
environment:
- ADMINER_DESIGN=pepa-linha-dark
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.rule=Host(`adminer.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.entrypoints=http
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.middlewares=https-redirect
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.rule=Host(`adminer.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls.certresolver=le
- traefik.http.services.${STACK_NAME?Variable not set}-adminer.loadbalancer.server.port=8080

prestart:
image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
build:
context: .
dockerfile: backend/Dockerfile
networks:
- traefik-public
- default
depends_on:
db:
condition: service_healthy
Expand All @@ -58,30 +32,16 @@ services:
env_file:
- .env
environment:
- DOMAIN=${DOMAIN}
- FRONTEND_HOST=${FRONTEND_HOST?Variable not set}
- ENVIRONMENT=${ENVIRONMENT}
- BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
- SECRET_KEY=${SECRET_KEY?Variable not set}
- FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set}
- FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set}
- SMTP_HOST=${SMTP_HOST}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}
- EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL}
- POSTGRES_SERVER=db
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER?Variable not set}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- SENTRY_DSN=${SENTRY_DSN}
- ENVIRONMENT=${ENVIRONMENT}

backend:
image: '${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}'
restart: always
networks:
- traefik-public
- default
depends_on:
db:
condition: service_healthy
Expand All @@ -108,67 +68,28 @@ services:
- POSTGRES_USER=${POSTGRES_USER?Variable not set}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set}
- SENTRY_DSN=${SENTRY_DSN}

build:
context: .
dockerfile: backend/Dockerfile
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/utils/health-check/"]
interval: 10s
timeout: 5s
retries: 5

build:
context: .
dockerfile: backend/Dockerfile
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public

- traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=8000

- traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=Host(`api.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.entrypoints=http

- traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.rule=Host(`api.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls.certresolver=le

# Enable redirection for HTTP and HTTPS
- traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.middlewares=https-redirect

frontend:
image: '${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}'
restart: always
networks:
- traefik-public
- default
depends_on:
backend:
condition: service_healthy
build:
context: .
dockerfile: frontend/Dockerfile
args:
- VITE_API_URL=https://api.${DOMAIN?Variable not set}
- VITE_API_URL=
- NODE_ENV=production
labels:
- traefik.enable=true
- traefik.docker.network=traefik-public
- traefik.constraint-label=traefik-public

- traefik.http.services.${STACK_NAME?Variable not set}-frontend.loadbalancer.server.port=80

- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=Host(`dashboard.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.entrypoints=http

- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.rule=Host(`dashboard.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls.certresolver=le

# Enable redirection for HTTP and HTTPS
- traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.middlewares=https-redirect
volumes:
app-db-data:

networks:
traefik-public:
# Allow setting it to false for testing
external: true
59 changes: 59 additions & 0 deletions documentation/Proposals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Proposal 1

## Project Title
TradSync: Intelligent Job Management and Regulatory Compliance API for Trade Services

## Introduction
Small-to-medium trade enterprises (plumbing, electrical, and carpentry businesses) in New Zealand face heavy administrative burdens complying with strict Health & Safety regulations and Building Code standards while managing daily workflows. The problem addressed is the high operational friction and legal risk associated with manual job tracking, onsite hazard assessments, and regulatory compliance logging. The objective of this project is to develop a centralized job management API that structures field notes, manages client service records, and automatically flags compliance/safety risks against statutory checklists before a job is signed off. The expected benefit is a significant reduction in administrative overhead for tradies, improved onsite safety tracking, and automated, legally sound documentation for council auditing.

## Technologies and Tools Used
The project will be built using the FastAPI full-stack template:
* **Backend:** Python and FastAPI to build asynchronous endpoints handling incoming job telemetry, materials logging, and automated compliance-checking algorithms.
* **Frontend:** React to build a responsive, scannable field-technician dashboard and an administrative command center for tracking active work sites.
* **Database:** PostgreSQL to map complex relational data models, including many-to-many relationships between jobs, field technicians, materials, hazard reports, and statutory compliance clauses.
* **Validation & Security:** Pydantic and SQLModel for rigid input sanitization (ensuring onsite safety data is complete), combined with OAuth2/JWT for role-based access control (separating Apprentices, Certified Tradesmen, and Auditors).

## Final Outcome
The final deliverable will be a deployed full-stack job management prototype tailored for trade industries. Field workers can log job details, track billable hours, and complete interactive, rule-based site safe/compliance checklists. The system features an automated report exporter that compiles immutable job histories and compliance logs into structured summaries. This serves as a highly relevant portfolio piece for the booming construction-technology (ConTech) and regulatory-technology (RegTech) sectors.

---

# Proposal 2

## Project Title
FinLaw: Automated Financial Compliance Workflow and Regulatory Audit System

## Introduction
The financial sector requires rigorous adherence to volatile anti-money laundering (AML) laws and legal compliance frameworks, which currently involves highly inefficient, manual reviews of extensive documentation. This project addresses the operational bottleneck and high human-error risks associated with manual legal compliance checks. The objective is to engineer an automated, state-machine driven document workflow system that tracks, flags, and audits financial documents against predefined compliance rules. The expected impact is a drastic reduction in administrative overhead, institutional legal risks, and a bulletproof, software-driven auditing trail for financial institutions.

## Technologies and Tools Used
This project will be built upon the provided FastAPI full-stack template:
* **Backend:** Python and FastAPI leveraging asynchronous endpoints to simulate concurrent document ingestion and high-performance parsing.
* **Frontend:** React to build an interactive administrative dashboard featuring an interactive Kanban workflow and compliance risk matrices.
* **Database:** PostgreSQL utilizing transactional isolation levels to guarantee the integrity of document metadata and immutable compliance logs, replacing lightweight solutions like SQLite3 for production-grade reliability.
* **ORM & Data Validation:** SQLModel/SQLAlchemy and Pydantic for rigid data-typing, schema enforcement, and input sanitization against legal data fields.
* **Containerization:** Docker and Docker Compose for consistent deployment pipelines and isolated environment management.

## Final Outcome
The final deliverable will be a deployed full-stack compliance web application. The system will allow compliance officers to upload financial document records, transition them through a strict, rule-based Kanban workflow, and automatically generate structured, tamper-proof compliance audit reports. This system bridges the gap between legal rigor and software engineering, making it a highly relevant prototype for modern RegTech (Regulatory Technology) ecosystems.

---

# Proposal 3

## Project Title
ForeXchange: High-Availability Real-Time Remittance and Compliance Telemetry Dashboard

## Introduction
While basic currency applications handle simple static conversions, commercial cross-border remittance demands highly scalable architectures, real-time telemetry (rate tracking), and rigid compliance checks to prevent financial crime. This project addresses the lack of transparent, secure, and production-ready architectures for monitoring international money exchanges. The objective is to engineer a robust, database-driven foreign exchange platform that seamlessly handles concurrent user sessions, live rate simulations, automated fee compliance calculations, and immutable transaction histories.

## Technologies and Tools Used
The solution will leverage the modern Python web ecosystem via the FastAPI template:
* **Core Backend:** Python 3 and FastAPI utilizing background tasks to process algorithmic currency conversion and transactional compliance checking.
* **Frontend:** React for a responsive, state-managed single-page application (SPA) tracking live market fluctuations.
* **Database Management:** PostgreSQL with strict relational constraints to secure ledger data, migrating local SQLite3 prototypes to an enterprise client-server model.
* **Authentication & Security:** OAuth2 with Password Flow and JWT tokens integrated natively into the FastAPI pipeline to enforce secure, role-based user sessions (e.g., Customer vs. Compliance Auditor).
* **Deployment:** Dockerized microservices orchestrated with Traefik for automated reverse proxy, SSL termination, and load balancing.

## Final Outcome
The expected outcome is a fully functional, containerized prototype of an enterprise money exchange platform. It will feature a secure multi-tier login system, an interactive dashboard visualizing live simulated currency trends, and an immutable ledger module that records and flags simulated cross-border remittance transactions. The architecture demonstrates modern software principles required in both FinTech and telemetry-driven industrial software engineering.
23 changes: 20 additions & 3 deletions frontend/nginx-backend-not-found.conf
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
resolver 127.0.0.11 ipv6=off;

location /api {
return 404;
set $backend http://backend:8000;
proxy_pass $backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /docs {
return 404;
set $backend http://backend:8000;
proxy_pass $backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /redoc {
return 404;
set $backend http://backend:8000;
proxy_pass $backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Loading