diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d81b5acf7519aac938ed92dab9bd611d95d2dbe2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/frontend/.env.local
diff --git a/backend/app/main.py b/backend/app/main.py
index 058b19437b3eea2c991cb1a9852bd1e044523376..1e81c49811d30e99907ba52c899fdc27a7893e6c 100644
--- a/backend/app/main.py
+++ b/backend/app/main.py
@@ -2,12 +2,20 @@
 
 from fastapi import FastAPI
 from fastapi.middleware.cors import CORSMiddleware
+from app import ssl_heidi
+from pathlib import Path
+
 
 from app.routers import address, contact, proposal, dewar, shipment, puck, spreadsheet, logistics
 from app.database import Base, engine, SessionLocal, load_sample_data
 
 app = FastAPI()
 
+# Generate SSL Key and Certificate if not exist
+Path("ssl").mkdir(parents=True, exist_ok=True)
+if not Path("ssl/cert.pem").exists() or not Path("ssl/key.pem").exists():
+    ssl_heidi.generate_self_signed_cert("ssl/cert.pem", "ssl/key.pem")
+
 # Apply CORS middleware
 app.add_middleware(
     CORSMiddleware,
@@ -39,9 +47,11 @@ app.include_router(dewar.router, prefix="/dewars", tags=["dewars"])
 app.include_router(shipment.router, prefix="/shipments", tags=["shipments"])
 app.include_router(puck.router, prefix="/pucks", tags=["pucks"])
 app.include_router(spreadsheet.router, tags=["spreadsheet"])
-app.include_router(dewar.router, prefix="/logistics", tags=["logistics"])
+app.include_router(logistics.router, prefix="/logistics", tags=["logistics"])
+
 
 if __name__ == "__main__":
-    import uvicorn
+    ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
+    ssl_context.load_cert_chain(certfile="ssl/cert.pem", keyfile="ssl/key.pem")
 
-    uvicorn.run(app, host="127.0.0.1", port=8000, log_level="debug")
+    uvicorn.run(app, host="127.0.0.1", port=8000, log_level="debug", ssl_context=ssl_context)
diff --git a/backend/app/routers/logistics.py b/backend/app/routers/logistics.py
index 8c80501a4fb64cd091e2e3131d4d1a917fe495b9..6680488fcdea0f7ae697a2519c0b895b561fda40 100644
--- a/backend/app/routers/logistics.py
+++ b/backend/app/routers/logistics.py
@@ -1,56 +1,96 @@
 from fastapi import APIRouter, HTTPException, Depends
 from sqlalchemy.orm import Session
+import logging
 from datetime import datetime, timedelta
 from typing import List
-
 from app.models import Dewar as DewarModel, Slot as SlotModel, LogisticsEvent as LogisticsEventModel
-from app.schemas import LogisticsEventCreate, SlotCreate, Slot as SlotSchema
+from app.schemas import LogisticsEventCreate, SlotCreate, Slot as SlotSchema, Dewar as DewarSchema
 from app.database import get_db
 
 router = APIRouter()
 
-@router.post("/scan-dewar")
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger(__name__)
+
+@router.get("/dewars", response_model=List[DewarSchema])
+async def get_all_prouts(db: Session = Depends(get_db)):
+    try:
+        dewars = db.query(DewarModel).all()
+        logging.info(f"Retrieved {len(dewars)} dewars from the database")
+        return dewars
+    except Exception as e:
+        logger.error(f"An error occurred: {e}")
+        raise HTTPException(status_code=500, detail="Internal server error")
+
+@router.get("/dewar/{qr_code}", response_model=DewarSchema)
+async def get_dewar_by_qr_code(qr_code: str, db: Session = Depends(get_db)):
+    logger.info(f"Received qr_code: {qr_code}")
+
+    trimmed_qr_code = qr_code.strip()
+    logger.info(f"Trimmed qr_code after stripping: {trimmed_qr_code}")
+
+    try:
+        dewar = db.query(DewarModel).filter(DewarModel.unique_id == trimmed_qr_code).first()
+        logger.info(f"Query Result: {dewar}")
+
+        if dewar:
+            return dewar
+        else:
+            logger.error(f"Dewar not found for unique_id: {trimmed_qr_code}")
+            raise HTTPException(status_code=404, detail="Dewar not found")
+    except Exception as e:
+        logger.error(f"An error occurred: {e}")
+        raise HTTPException(status_code=500, detail="Internal server error")
+
+@router.post("/dewar/scan", response_model=LogisticsEventCreate)
 async def scan_dewar(event_data: LogisticsEventCreate, db: Session = Depends(get_db)):
     dewar_qr_code = event_data.dewar_qr_code
     location_qr_code = event_data.location_qr_code
     transaction_type = event_data.transaction_type
 
-    dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first()
-    if not dewar:
-        raise HTTPException(status_code=404, detail="Dewar not found")
-
-    if transaction_type == 'incoming':
-        slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
-        if not slot or slot.occupied:
-            raise HTTPException(status_code=404, detail="Slot not found or already occupied")
-        slot.occupied = True
-        log_event(db, dewar.id, slot.id, 'incoming')
-
-    elif transaction_type == 'beamline':
-        log_event(db, dewar.id, None, 'beamline')
-
-    elif transaction_type == 'outgoing':
-        slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
-        if not slot or not slot.occupied:
-            raise HTTPException(status_code=404, detail="Slot not found or not occupied")
-        slot.occupied = False
-        log_event(db, dewar.id, slot.id, 'outgoing')
-
-    elif transaction_type == 'release':
-        slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
-        if not slot or not slot.occupied:
-            raise HTTPException(status_code=404, detail="Slot not found or not occupied")
-        slot.occupied = False
-        log_event(db, dewar.id, slot.id, 'released')
+    try:
+        dewar = db.query(DewarModel).filter(DewarModel.unique_id == dewar_qr_code).first()
+        if not dewar:
+            raise HTTPException(status_code=404, detail="Dewar not found")
 
-    db.commit()
-    return {"message": "Status updated successfully"}
+        if transaction_type == 'incoming':
+            slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
+            if not slot or slot.occupied:
+                raise HTTPException(status_code=404, detail="Slot not found or already occupied")
+            slot.occupied = True
+            log_event(db, dewar.id, slot.id, 'incoming')
+
+        elif transaction_type == 'beamline':
+            log_event(db, dewar.id, None, 'beamline')
+
+        elif transaction_type == 'outgoing':
+            slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
+            if not slot or not slot.occupied:
+                raise HTTPException(status_code=404, detail="Slot not found or not occupied")
+            slot.occupied = False
+            log_event(db, dewar.id, slot.id, 'outgoing')
+
+        elif transaction_type == 'release':
+            slot = db.query(SlotModel).filter(SlotModel.id == location_qr_code).first()
+            if not slot or not slot.occupied:
+                raise HTTPException(status_code=404, detail="Slot not found or not occupied")
+            slot.occupied = False
+            log_event(db, dewar.id, slot.id, 'released')
+
+        db.commit()
+        logger.info(f"Status updated successfully for Dewar ID: {dewar.id}")
+        return {"message": "Status updated successfully"}
+    except Exception as e:
+        logger.error(f"An error occurred: {e}")
+        raise HTTPException(status_code=500, detail="Internal server error")
 
 def log_event(db: Session, dewar_id: int, slot_id: int, event_type: str):
-    new_event = LogisticsEventModel(dewar_id=dewar_id, slot_id=slot_id, event_type=event_type)
+    new_event = LogisticsEventModel(dewar_id=dewar_id if dewar_id else None, slot_id=slot_id, event_type=event_type)
     db.add(new_event)
+    db.commit()
+    logger.info(f"Logged event {event_type} for Dewar ID: {dewar_id}")
 
-@router.get("/refill-status", response_model=List[SlotSchema])
+@router.get("/slots/refill-status", response_model=List[SlotSchema])
 async def refill_status(db: Session = Depends(get_db)):
     slots_needing_refill = db.query(SlotModel).filter(SlotModel.needs_refill == True).all()
     result = []
diff --git a/backend/app/ssl_heidi.py b/backend/app/ssl_heidi.py
new file mode 100644
index 0000000000000000000000000000000000000000..3131b98a83670d6b47f98e61c7ddd966d82678e9
--- /dev/null
+++ b/backend/app/ssl_heidi.py
@@ -0,0 +1,52 @@
+# Generate SSL Key and Certificate
+from cryptography import x509
+from cryptography.x509.oid import NameOID
+from cryptography.hazmat.primitives import serialization, hashes
+from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.hazmat.primitives.serialization import Encoding
+import datetime
+
+
+def generate_self_signed_cert(cert_file: str, key_file: str):
+    # Generate private key
+    key = rsa.generate_private_key(
+        public_exponent=65537,
+        key_size=2048,
+    )
+    # Write private key to file
+    with open(key_file, "wb") as f:
+        f.write(key.private_bytes(
+            encoding=serialization.Encoding.PEM,
+            format=serialization.PrivateFormat.TraditionalOpenSSL,
+            encryption_algorithm=serialization.NoEncryption(),
+        ))
+
+    # Generate self-signed certificate
+    subject = issuer = x509.Name([
+        x509.NameAttribute(NameOID.COUNTRY_NAME, u"CH"),
+        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Argau"),
+        x509.NameAttribute(NameOID.LOCALITY_NAME, u"Villigen"),
+        x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Paul Scherrer Institut"),
+        x509.NameAttribute(NameOID.COMMON_NAME, u"PSI.CH"),
+    ])
+    cert = x509.CertificateBuilder().subject_name(
+        subject
+    ).issuer_name(
+        issuer
+    ).public_key(
+        key.public_key()
+    ).serial_number(
+        x509.random_serial_number()
+    ).not_valid_before(
+        datetime.datetime.utcnow()
+    ).not_valid_after(
+        # Our certificate will be valid for 10 days
+        datetime.datetime.utcnow() + datetime.timedelta(days=10)
+    ).add_extension(
+        x509.SubjectAlternativeName([x509.DNSName(u"localhost")]),
+        critical=False,
+    ).sign(key, hashes.SHA256())
+
+    # Write certificate to file
+    with open(cert_file, "wb") as f:
+        f.write(cert.public_bytes(Encoding.PEM))
\ No newline at end of file
diff --git a/frontend/src/components/ShipmentForm.tsx b/frontend/src/components/ShipmentForm.tsx
index 9e69d23439803d2394a1f791c4edbbb5cfc1b0e4..ba2b56b6ad8c970dbf91bbcb7f2bdd2fcbe06948 100644
--- a/frontend/src/components/ShipmentForm.tsx
+++ b/frontend/src/components/ShipmentForm.tsx
@@ -39,7 +39,7 @@ const ShipmentForm: React.FC<ShipmentFormProps> = ({ sx = {}, onCancel, refreshS
     const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
 
     useEffect(() => {
-        OpenAPI.BASE = 'http://127.0.0.1:8000';
+        OpenAPI.BASE = 'https://127.0.0.1:8000';
 
         const getContacts = async () => {
             try {
diff --git a/frontend/src/components/UploadDialog.tsx b/frontend/src/components/UploadDialog.tsx
index e0c545a7022fcb23e28b7a6a4b17101039440ce9..dd9f3cb2388f2cef6cb21ff603d86551ec76dffb 100644
--- a/frontend/src/components/UploadDialog.tsx
+++ b/frontend/src/components/UploadDialog.tsx
@@ -46,7 +46,7 @@ const UploadDialog: React.FC<UploadDialogProps> = ({ open, onClose, selectedShip
     const fileInputRef = useRef<HTMLInputElement>(null);
 
     useEffect(() => {
-        OpenAPI.BASE = 'http://127.0.0.1:8000';
+        OpenAPI.BASE = 'https://127.0.0.1:8000';
     }, []);
 
     const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
diff --git a/frontend/src/pages/ShipmentView.tsx b/frontend/src/pages/ShipmentView.tsx
index 0cb9f762de84cd9904c0359297dc63659277a607..6265107d4d9dc8c3d67024328d94786f5b869b21 100644
--- a/frontend/src/pages/ShipmentView.tsx
+++ b/frontend/src/pages/ShipmentView.tsx
@@ -9,7 +9,7 @@ import { Grid, Container } from '@mui/material';
 // Define props for Shipments View
 type ShipmentViewProps = React.PropsWithChildren<Record<string, never>>;
 
-const API_BASE_URL = 'http://127.0.0.1:8000';
+const API_BASE_URL = 'https://127.0.0.1:8000';
 OpenAPI.BASE = API_BASE_URL;
 
 const ShipmentView: React.FC<ShipmentViewProps> = () => {
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 8b966869e727f5f3c2b8ec5c91601eb7aa15e28e..027bdb4e329042540cc4c22a69937d9f8a2e4bae 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -1,7 +1,18 @@
-import { defineConfig } from 'vite';
+import { defineConfig, loadEnv  } from 'vite';
 import react from '@vitejs/plugin-react';
-export default defineConfig({
-  plugins: [
-    react(),
-  ],
+import path from 'path';
+
+export default defineConfig(({ mode }) => {
+  const env = loadEnv(mode, process.cwd(), '');
+
+  return {
+    plugins: [
+      react(),
+    ],
+    server: {
+      https: {
+        key: env.VITE_SSL_KEY_PATH,
+        cert: env.VITE_SSL_CERT_PATH,
+      }
+  }}
 });
\ No newline at end of file
diff --git a/logistics/src/components/Slots.tsx b/logistics/src/components/Slots.tsx
index 7ce78e37ef756a1e1021908bacee74cc0fd68f87..359690ca0d93dfd849470d9efcb3843c0bdfeec8 100644
--- a/logistics/src/components/Slots.tsx
+++ b/logistics/src/components/Slots.tsx
@@ -16,12 +16,12 @@ export interface SlotData {
     timeUntilRefill: string;
 }
 
-const SlotContainer = styled(Box)<{ occupied: boolean, isSelected: boolean }>`
+const SlotContainer = styled(Box)<{ isOccupied: boolean, isSelected: boolean }>`
     width: 90px;
     height: 180px;
     margin: 10px;
-    background-color: ${(props) => (props.occupied ? '#f0f0f0' : '#ffffff')};
-    border: ${(props) => (props.isSelected ? '3px solid blue' : '2px solid #aaaaaa')};
+    background-color: ${({ isOccupied }) => (isOccupied ? '#ffebee' : '#e8f5e9')}; /* occupied = light red, free = light green */
+    border: ${({ isSelected }) => (isSelected ? '3px solid blue' : '2px solid #aaaaaa')};
     border-radius: 5px;
     box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
     display: flex;
@@ -56,14 +56,16 @@ const ClockIcon = styled(AccessTime)`
 `;
 
 const Slot: React.FC<SlotProps> = ({ data, onSelect, isSelected }) => {
+    const { id, occupied, needsRefill, timeUntilRefill } = data;
+
     return (
-        <SlotContainer occupied={data.occupied} onClick={() => onSelect(data)} isSelected={isSelected}>
-            <SlotNumber>{data.id}</SlotNumber>
+        <SlotContainer isOccupied={occupied} onClick={() => onSelect(data)} isSelected={isSelected}>
+            <SlotNumber>{id}</SlotNumber>
             <QrCodeIcon />
-            {data.occupied && (
+            {occupied && (
                 <>
-                    {data.needsRefill && <RefillIcon titleAccess="Needs Refill" />}
-                    <ClockIcon titleAccess={`Time until refill: ${data.timeUntilRefill}`} />
+                    {needsRefill && <RefillIcon titleAccess="Needs Refill" />}
+                    <ClockIcon titleAccess={`Time until refill: ${timeUntilRefill}`} />
                 </>
             )}
         </SlotContainer>
diff --git a/logistics/src/components/Storage.tsx b/logistics/src/components/Storage.tsx
index 02b8e5cf1f29d09207d7981f48bb73f4a3baecc0..cb8d90ec5243392fa23a233da66e3fb028d03381 100644
--- a/logistics/src/components/Storage.tsx
+++ b/logistics/src/components/Storage.tsx
@@ -96,7 +96,12 @@ const Storage: React.FC<StorageProps> = ({ name, selectedSlot }) => {
             <Typography variant="h5">{name} Slots</Typography>
             <StorageWrapper>
                 {storageSlotsData[name].map((slot) => (
-                    <Slot key={slot.id} data={slot} onSelect={handleSlotSelect} isSelected={selectedSlot === slot.id} />
+                    <Slot
+                        key={slot.id}
+                        data={slot}
+                        onSelect={handleSlotSelect}
+                        isSelected={selectedSlot === slot.id}
+                    />
                 ))}
             </StorageWrapper>
             {highlightedSlot && (
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1e8dbb48cce2e77cd5fa044b5d34be8277e706b9
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+SQLAlchemy~=2.0.36
+fastapi~=0.115.4
+pydantic~=2.9.2
+openpyxl~=3.1.5
+typing_extensions~=4.12.2
\ No newline at end of file