Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 322 additions & 0 deletions submissions/Touqeer-Hamdani/level5/answers.md

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions submissions/Touqeer-Hamdani/level5/schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Factory Knowledge Graph — Schema

```mermaid
graph LR
%% ── Node definitions ──
Project["🏗️ <b>Project</b><br/>project_id · project_number<br/>project_name"]
Product["📦 <b>Product</b><br/>product_type · unit"]
Station["🏭 <b>Station</b><br/>station_code · station_name"]
Worker["👷 <b>Worker</b><br/>worker_id · name<br/>role · hours_per_week · type"]
Week["📅 <b>Week</b><br/>week_id"]
Factory["🏭 <b>Factory</b><br/>factory_name"]
Certification["🎓 <b>Certification</b><br/>cert_name"]
Etapp["🔄 <b>Etapp</b><br/>etapp_name"]

%% ── Relationships ──
Project -->|"PRODUCES<br/>{quantity, unit_factor, unit}"| Product
Project -->|"SCHEDULED_AT<br/>{planned_hours, actual_hours, week,<br/>completed_units, etapp, bop, variance_pct}"| Station
Project -->|"ACTIVE_IN"| Week
Project -->|"IN_PHASE"| Etapp

Worker -->|"WORKS_AT"| Station
Worker -->|"CAN_COVER"| Station
Worker -->|"HOLDS"| Certification

Station -->|"LOADED_IN<br/>{total_planned,<br/>total_actual}"| Week
Week -->|"HAS_CAPACITY<br/>{own_hours, hired_hours, overtime_hours, total_planned, deficit}"| Factory

%% ── Styling ──
classDef proj fill:#4F46E5,stroke:#3730A3,color:#fff,rx:12
classDef prod fill:#059669,stroke:#047857,color:#fff,rx:12
classDef stat fill:#D97706,stroke:#B45309,color:#fff,rx:12
classDef work fill:#DC2626,stroke:#B91C1C,color:#fff,rx:12
classDef week fill:#7C3AED,stroke:#6D28D9,color:#fff,rx:12
classDef meta fill:#6B7280,stroke:#4B5563,color:#fff,rx:12
classDef cert fill:#0891B2,stroke:#0E7490,color:#fff,rx:12
classDef etap fill:#E11D48,stroke:#BE123C,color:#fff,rx:12

class Project proj
class Product prod
class Station stat
class Worker work
class Week week
class Factory meta
class Certification cert
class Etapp etap
```

## Node Labels (8)

| # | Label | Source CSV | Key Properties | Count |
|---|-------|-----------|----------------|-------|
| 1 | **Project** | production.csv | project_id, project_number, project_name | 8 |
| 2 | **Product** | production.csv | product_type, unit | 7 (IQB, IQP, SB, SD, SP, SR, HSQ) |
| 3 | **Station** | production.csv | station_code, station_name | 10 (011–019, 021) |
| 4 | **Worker** | workers.csv | worker_id, name, role, hours_per_week, type | 14 |
| 5 | **Week** | capacity.csv | week_id | 8 (w1–w8) |
| 6 | **Factory** | Implicit | factory_name | 1 |
| 7 | **Certification** | workers.csv | cert_name | 23 unique certs |
| 8 | **Etapp** | production.csv | etapp_name | 2 (ET1, ET2) |

## Relationship Types (9)

| # | Relationship | From → To | Properties (data-carrying?) |
|---|-------------|-----------|----------------------------|
| 1 | **PRODUCES** | Project → Product | ✅ `{quantity, unit_factor, unit}` |
| 2 | **SCHEDULED_AT** | Project → Station | ✅ `{planned_hours, actual_hours, completed_units, week, etapp, bop, variance_pct}` |
| 3 | **ACTIVE_IN** | Project → Week | — |
| 4 | **IN_PHASE** | Project → Etapp | — |
| 5 | **WORKS_AT** | Worker → Station | — (primary station) |
| 6 | **CAN_COVER** | Worker → Station | — (coverage capability) |
| 7 | **HOLDS** | Worker → Certification | — |
| 8 | **LOADED_IN** | Station → Week | ✅ `{total_planned, total_actual}`* |
| 9 | **HAS_CAPACITY**| Week → Factory | ✅ `{own_hours, hired_hours, overtime_hours, total_planned, deficit}` |

> 4 relationships carry data properties (**PRODUCES**, **SCHEDULED_AT**, **LOADED_IN**, **HAS_CAPACITY**), exceeding the minimum of 2.
>
> *\*Note: `LOADED_IN` properties are calculated by aggregating the `SCHEDULED_AT` edges for each station/week.*
>
> *\*Note: `etapp` is also kept as a property on `SCHEDULED_AT` for direct querying. The `Etapp` node is included for L6 compliance, but from a pure design perspective, etapp works better as an edge property since it only has 2 values and carries no properties of its own.*
3 changes: 3 additions & 0 deletions submissions/Touqeer-Hamdani/level6/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NEO4J_URI = "neo4j+s://xxxxx.databases.neo4j.io"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "your-password"
Comment on lines +1 to +3
1 change: 1 addition & 0 deletions submissions/Touqeer-Hamdani/level6/DASHBOARD_URL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://l6-factory-dashboard-touqeerhamdani.streamlit.app
69 changes: 69 additions & 0 deletions submissions/Touqeer-Hamdani/level6/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Factory Knowledge Graph Dashboard — Level 6

A **Neo4j knowledge graph** + **Streamlit dashboard** for a Swedish steel fabrication company managing 8 construction projects across 10 production stations.

## Quick Start

### 1. Prerequisites
- Python 3.10+
- A Neo4j instance (recommended: [Neo4j Aura Free](https://neo4j.io/aura))

### 2. Setup
```bash
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # macOS/Linux
pip install -r requirements.txt
```

### 3. Configure credentials
Copy `.env.example` → `.env` and fill in your Neo4j credentials:
```
NEO4J_URI=neo4j+s://xxxxx.databases.neo4j.io
NEO4J_USER=neo4j
NEO4J_PASSWORD=your-password
```

### 4. Seed the graph (run once)
```bash
python seed_graph.py
```

### 5. Launch the dashboard
```bash
streamlit run app.py
```

## Dashboard Pages

| Page | Description |
|------|-------------|
| **Project Overview** | All 8 projects with planned/actual hours, variance %, and products |
| **Station Load** | Interactive bar chart — hours per station per week, overloads in red |
| **Capacity Tracker** | Stacked capacity bars + demand line, deficit weeks highlighted |
| **Worker Coverage** | Coverage matrix + SPOF (single-point-of-failure) station detection |
| **Self-Test** | Automated 6-check verification (20 pts) |
Comment on lines +41 to +45

## Project Structure

```
l6-factory-dashboard/
├── seed_graph.py # CSV → Neo4j (idempotent, uses MERGE)
├── app.py # Streamlit dashboard (5 pages)
├── requirements.txt
├── .env.example
├── README.md
├── DASHBOARD_URL.txt
└── data/
├── factory_production.csv
├── factory_workers.csv
└── factory_capacity.csv
```

## Deployed URL

See `DASHBOARD_URL.txt`.

## Author

**Touqeer Hamdani** — Level 6 submission, May 2026.
Loading
Loading