# Web app

# Getting Started

## Tech Stack

- **Language:**<span style="white-space: pre-wrap;"> Python 3.14 (Managed via Nix)</span>
- **Framework:**<span style="white-space: pre-wrap;"> Django</span>
- **Package Manager:**<span style="white-space: pre-wrap;"> </span>[uv](https://github.com/astral-sh/uv)<span style="white-space: pre-wrap;"> (Fastest Python resolver/installer)</span>
- **Environment:**<span style="white-space: pre-wrap;"> </span>[Nix](https://nixos.org/)<span style="white-space: pre-wrap;"> (with the </span>`<span class="editor-theme-code">std</span>`<span style="white-space: pre-wrap;"> library)</span>
- **Command Runner:**<span style="white-space: pre-wrap;"> </span>`<span class="editor-theme-code">just</span>`<span style="white-space: pre-wrap;"> (alternative to </span>`<span class="editor-theme-code">make</span>`)

## Setting Up the Environment

<p class="callout danger">FIXME: this is wrong</p>

<span style="white-space: pre-wrap;">You do not need to install Python or Django manually. You only need </span>**Nix**.

### Step 1: Install Nix

If you don't have it, install Nix and enable “experimental features” (Flakes and Nix Command).

Consider doing the latter like that:  
<span style="white-space: pre-wrap;">1) </span>`<span class="editor-theme-code">sudo mkdir /root/.config/nix </span>`

<span style="white-space: pre-wrap;">2) </span>`<span class="editor-theme-code">sudoedit /root/.config/nix/nix.conf</span>`

<span style="white-space: pre-wrap;">3) In there, add this line </span>`<span class="editor-theme-code">experimental-features = nix-command flakes</span>`

### Step 2: Enter the Development Shell

Navigate to the project root and run:

`<span class="editor-theme-code">nix develop</span>`

**What happens when you run this?**<span style="white-space: pre-wrap;"> Nix reads </span>`<span class="editor-theme-code">shells.nix</span>`<span style="white-space: pre-wrap;"> and </span>`<span class="editor-theme-code">packages.nix</span>`<span style="white-space: pre-wrap;"> to:</span>

1. <span style="white-space: pre-wrap;">Download and provide </span>**Python 3.14**.
2. <span style="white-space: pre-wrap;">Install system tools like </span>`<span class="editor-theme-code">curl</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">git</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">uv</span>`<span style="white-space: pre-wrap;">, and </span>`<span class="editor-theme-code">just</span>`.
3. <span style="white-space: pre-wrap;">Set up your </span>`<span class="editor-theme-code">PATH</span>`<span style="white-space: pre-wrap;"> to include the project’s virtual environment (</span>`<span class="editor-theme-code">.venv/bin</span>`).
4. Activate a custom shell prompt (the “embed console”).

### Step 3: The “Just” Command Runner

<span style="white-space: pre-wrap;">Once inside the Nix shell, we use a tool called </span>`<span class="editor-theme-code">just</span>`<span style="white-space: pre-wrap;"> to run common tasks.</span>

<table id="bkmrk-commandactionjustlis" style="margin-bottom: 32px;"><colgroup><col></col><col></col></colgroup><tbody><tr><td style="border: 1px solid;">**Command**

</td><td style="border: 1px solid;">**Action**

</td></tr><tr><td style="border: 1px solid;">`<span class="editor-theme-code">just</span>`

</td><td style="border: 1px solid;">Lists all available commands.

</td></tr><tr><td style="border: 1px solid;">**`<strong class="editor-theme-bold editor-theme-code">just init-db</strong>`**

</td><td style="border: 1px solid;">**Run this first.**<span style="white-space: pre-wrap;"> It migrates the DB and asks you to create a Superuser.</span>

</td></tr><tr><td style="border: 1px solid;">**`<strong class="editor-theme-bold editor-theme-code">just dev</strong>`**

</td><td style="border: 1px solid;">Starts the Django development server.

</td></tr><tr><td style="border: 1px solid;">`<span class="editor-theme-code">just make-migrations</span>`

</td><td style="border: 1px solid;">Generates new DB migration files after model changes.

</td></tr><tr><td style="border: 1px solid;">`<span class="editor-theme-code">just fmt</span>`

</td><td style="border: 1px solid;"><span style="white-space: pre-wrap;">Automatically formats all code using </span>`<span class="editor-theme-code">treefmt</span>`.

</td></tr><tr><td style="border: 1px solid;">`<span class="editor-theme-code">just test</span>`

</td><td style="border: 1px solid;">Runs the Django test suite.

</td></tr></tbody></table>

### Step 4: Running the dev server

Consider using these commands after all previous steps:

`<span class="editor-theme-code">nix init-db </span>`<span style="white-space: pre-wrap;"> creates and initializes the DB, prompting for superuser credentials.</span>  
`<span class="editor-theme-code">nix dev </span>`<span style="white-space: pre-wrap;"> starts a local dev server.</span>  
**Congratulations! You are ready to develop.**

# Structure of the project

## Architecture &amp; Frontend Patterns (Midas)

<span style="white-space: pre-wrap;">The RFID Tracker (codename </span>**Midas**) follows a traditional Django structure but uses a “Single File Component” philosophy for its views.

## Project Organization

The project is split into the core configuration and the functional app logic.

<table id="bkmrk-directory-%2F-filerole"><colgroup><col></col><col></col></colgroup><tbody><tr><td>**Directory / File**

</td><td>**Role**

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">midas/</strong>`**

</td><td>The active module containing the latest logic, models, and views.

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">webui/</strong>`**

</td><td><span style="white-space: pre-wrap;">Legacy code kept for bookkeeping; </span>**do not use**<span style="white-space: pre-wrap;"> for new features.</span>

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">templates/midas/</strong>`**

</td><td>The “Face” of the app. Contains HTML layouts, CSS, and JS.

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">models.py</strong>`**

</td><td>Database schema (RFID tags, teams, hours).

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">views.py</strong>`**

</td><td>The “Controller.” Fetches data from DB and performs calculations.

</td></tr><tr><td>**`<strong class="editor-theme-bold editor-theme-code">urls.py</strong>`**

</td><td><span style="white-space: pre-wrap;">Maps URLs to specific Python functions in </span>`<span class="editor-theme-code">views.py</span>`.

</td></tr></tbody></table>

---

## The Frontend Pattern

### Layout Strategy

Every page follows this block-based hierarchy:

1. **`<strong class="editor-theme-bold editor-theme-code">{% extends 'midas/base.html' %}</strong>`**: Inherits the sidebar, navbar, and global styles.
2. **`<strong class="editor-theme-bold editor-theme-code">{% block head %}</strong>`**: Contains page-specific CSS and external libraries (like Chart.js).
3. **`<strong class="editor-theme-bold editor-theme-code">{% block main %}</strong>`**: The actual HTML content (cards, forms, tables).
4. **`<strong class="editor-theme-bold editor-theme-code"><script></strong>`**: Local logic for charts or UI interactions.

## The “Data Bridge” (Python to JavaScript)

To keep the code clean and secure, we use a specific pattern to pass data from the Python backend to the JavaScript frontend.

### <span style="white-space: pre-wrap;">The </span>`<span class="editor-theme-code">json_script</span>`<span style="white-space: pre-wrap;"> Filter</span>

<span style="white-space: pre-wrap;">Instead of messy string concatenation, we use Django's </span>`<span class="editor-theme-code">json_script</span>`<span style="white-space: pre-wrap;"> tag. This safely injects Python dictionaries into the HTML as a JSON object that JS can read.</span>

**In the HTML Template:**  
`<span class="editor-theme-code">{{ page_data|json_script:"frontend-data" }}</span>`

**In the JavaScript block:**  
`<span class="editor-theme-code">const appData = JSON.parse(document.getElementById('frontend-data').textContent);</span>`  
`<span class="editor-theme-code">// Now appData.chart.labels is ready for Chart.js!</span>`

## Backend Logic &amp; Calculation

The heavy lifting is done in the Python files before the page even loads:

- **Calculations:**<span style="white-space: pre-wrap;"> Logic like “Total Hours” or “Avg per Member” is calculated in </span>`<span class="editor-theme-code">views.py</span>`<span style="white-space: pre-wrap;"> or helper files like </span>`<span class="editor-theme-code">statistics.py</span>`.
- **Database Interaction:**<span style="white-space: pre-wrap;"> Uses Django’s ORM (Object-Relational Mapper) to query the </span>`<span class="editor-theme-code">db.sqlite3</span>`<span style="white-space: pre-wrap;"> (dev) or the production DB.</span>
- **Forms:**<span style="white-space: pre-wrap;"> Django’s </span>`<span class="editor-theme-code">forms.py</span>`<span style="white-space: pre-wrap;"> handles input validation when you change dates or teams in the dashboard.</span>

## Admin dashboard

Django provides its own built-in admin dashboard which can be reached through “Admin Dashboard” button on the sidebar. (if you are a superuser).