Skip to content

Commit a823694

Browse files
author
flaggz
committed
updated readme
1 parent e158ef0 commit a823694

1 file changed

Lines changed: 74 additions & 22 deletions

File tree

README.md

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## Mainplate — Watch Flip & Collection Tracker
22

3-
<img src="/app/static/img/logo_mainplate.png" width="100">
3+
<img src="app/static/img/logo_mainplate.png" width="100">
4+
45
A self-hosted web app for watch enthusiasts and watchmakers to track personal collection, flips, parts inventory, and equipment — all in one place.
56

67
Built with Flask + SQLite, runs entirely in Docker with no external dependencies.
@@ -17,20 +18,18 @@ Built with Flask + SQLite, runs entirely in Docker with no external dependencies
1718

1819
| Light Mode | Dark Mode |
1920
|:----------:|:---------:|
20-
| ![Dashboard](/screens/dashboard.jpg "Dashboard") | ![Dashboard Dark](/screens/dashboard_dark.jpg "Dashboard Dark mode") |
21-
| ![Flips](/screens/flips.jpg "Flips") | ![Flips Dark](/screens/flips_dark.jpg "Flips Dark mode") |
22-
| ![Flips](/screens/flips_add.jpg "Add Flips") | ![Flips Dark](/screens/flips_add_dark.jpg "Add Flips Dark mode") |
23-
| ![Flips](/screens/flips_detail.jpg "Flips Detail") | ![Flips Dark](/screens/flips_detail_dark.jpg "Flips Detail Dark mode") |
24-
| ![Collection](/screens/collection.jpg "Collection") | ![Collection Dark](/screens/collection_dark.jpg "Collection Dark Mode") |
25-
| ![Collection](/screens/collection_add.jpg "Add Collection") | ![Collection Dark](/screens/collection_add_dark.jpg "Add Collection Dark Mode") |
26-
| ![Equipment](/screens/equipment.jpg "Equipment") | ![Equipment Dark](/screens/equipment_dark.jpg "Equipment Dark Mode") |
27-
| ![Inventory](/screens/inventory.jpg "Inventory") | ![Inventory Dark](/screens/inventory_dark.jpg "Inventory Dark Mode") |
28-
| ![Settings](/screens/settings.jpg "Settings") | ![Settings Dark](/screens/settings_dark.jpg "Settings Dark Mode") |
21+
| ![Dashboard](screens/dashboard.jpg "Dashboard") | ![Dashboard Dark](screens/dashboard_dark.jpg "Dashboard Dark mode") |
22+
| ![Flips](screens/flips.jpg "Flips") | ![Flips Dark](screens/flips_dark.jpg "Flips Dark mode") |
23+
| ![Flips](screens/flips_add.jpg "Add Flips") | ![Flips Dark](screens/flips_add_dark.jpg "Add Flips Dark mode") |
24+
| ![Flips](screens/flips_detail.jpg "Flips Detail") | ![Flips Dark](screens/flips_detail_dark.jpg "Flips Detail Dark mode") |
25+
| ![Collection](screens/collection.jpg "Collection") | ![Collection Dark](screens/collection_dark.jpg "Collection Dark Mode") |
26+
| ![Collection](screens/collection_add.jpg "Add Collection") | ![Collection Dark](screens/collection_add_dark.jpg "Add Collection Dark Mode") |
27+
| ![Equipment](screens/equipment.jpg "Equipment") | ![Equipment Dark](screens/equipment_dark.jpg "Equipment Dark Mode") |
28+
| ![Inventory](screens/inventory.jpg "Inventory") | ![Inventory Dark](screens/inventory_dark.jpg "Inventory Dark Mode") |
29+
| ![Settings](screens/settings.jpg "Settings") | ![Settings Dark](screens/settings_dark.jpg "Settings Dark Mode") |
2930

3031
---
3132

32-
33-
3433
## Features
3534

3635
| Section | Description |
@@ -42,13 +41,36 @@ Built with Flask + SQLite, runs entirely in Docker with no external dependencies
4241
| **Equipment** | Tools and instruments with total value |
4342
| **Settings** | Language, currency, date format, hourly rate, categories, and full ZIP backup/restore |
4443

44+
---
45+
46+
### Financial Tracking & ROI
47+
48+
Every flip is a complete financial record. Mainplate calculates total cost from the purchase price, every log entry expense, and labor hours billed at your configured hourly rate. Profit and **ROI %** are computed automatically once the flip is marked as sold — giving you a real picture of whether a job was worth your time.
49+
50+
The **Dashboard** aggregates everything: total capital deployed, realised profit, average ROI across all sold flips, and open inventory value. The **Collection** section tracks the same for personal watches — purchase price + service costs vs. eventual sale price, with a **gain/loss** figure per watch.
51+
52+
---
53+
54+
### Flip Status Workflow
55+
56+
Each flip moves through a four-stage lifecycle: **Acquired → In Progress → For Sale → Sold**. Stages are colour-coded throughout the UI. Only "Sold" flips contribute to the profit and ROI calculations, so your pipeline and closed deals are always kept separate.
57+
58+
---
59+
4560
### Photo Gallery
46-
Every flip and every collection watch supports **multiple photos**. Images are processed on upload (resized to max 2400 px on the long side, saved as JPEG at 85% quality) using Pillow. Photos are displayed as thumbnails in the list views and in a full gallery on the detail page, with drag-to-reorder support.
4761

48-
### Flip Log
49-
Each flip has a detailed log with **date + description + optional cost + category**. Log entries contribute to the net profit calculation and can optionally add parts to inventory automatically.
62+
Every flip and every collection watch supports **multiple photos**. Images are processed on upload (resized to max 2400 px on the long side, saved as JPEG at 85% quality) using Pillow. Accepted formats: JPEG, PNG, WebP, GIF, HEIC/HEIF. Transparent images are flattened before conversion. Photos are displayed as thumbnails in the list views and in a full lightbox gallery on the detail page, with **drag-to-reorder** support.
63+
64+
---
65+
66+
### Flip Log with Automatic Inventory Sync
67+
68+
Each flip has a detailed log with **date + description + optional cost + category**. Log entries contribute to the net profit calculation. Ticking the **"Add to inventory"** checkbox on a log entry automatically creates or updates the corresponding part in the Inventory section — quantity is incremented and cost is added. Deleting or editing the log entry keeps the inventory record in sync.
69+
70+
---
5071

5172
### Timegrapher
73+
5274
Each flip has a **timegrapher readings log** to record the movement's timing across the six standard positions (DU, DD, 3U, 6U, 9U, 12U), plus overall amplitude and beat error. Multiple readings are stored per flip — useful to compare before/after a service — with the latest reading shown as a summary at the top.
5375

5476
The **delta** (max − min spread across all positions) is computed automatically and colour-coded: green below 10 s/d, yellow 10–20 s/d, red above 20 s/d.
@@ -66,29 +88,59 @@ Each cell also carries **per-field diagnostic warnings** that highlight anomalie
6688
| 3U / 9U | diff > 15 s/d | warning — possible balance wheel poise issue |
6789
| 6U / 12U | diff > 15 s/d | warning — check lever or hairspring |
6890

91+
---
92+
6993
### Collection Log
70-
Each watch in the collection has a service diary (revisions, part replacements, etc.) with optional cost and category per entry.
94+
95+
Each watch in the collection has a service diary (revisions, part replacements, etc.) with optional cost and category per entry. All service costs roll up into the total cost basis for gain/loss tracking.
96+
97+
---
7198

7299
### Wishlist
100+
73101
The collection page includes a dedicated **Wishlist** tab for watches you want to acquire. Wishlist entries support the same fields as owned watches and can be promoted to the active collection at any time.
74102

103+
---
104+
75105
### Sold Watches
106+
76107
Watches in the collection can be marked as sold with a sale date and sale price. Sold items move to a dedicated tab with a **gain/loss** calculation (sale price minus purchase + service costs).
77108

109+
---
110+
78111
### Categories
79-
Log entry categories are managed from Settings with a **name + color** per category. The same category list is shared across flip logs, collection logs, and inventory, ensuring consistency throughout the app.
112+
113+
Log entry categories are managed from Settings with a **name + color** per category. A built-in color picker with live hex preview makes it easy to assign distinct colours. The same category list is shared across flip logs, collection logs, and inventory, ensuring consistency throughout the app.
114+
115+
---
80116

81117
### Watch Lookup
82-
When adding a new flip or collection watch, a **Chrono24 search** field appears at the top of the form. Type a brand, model, or reference number and select a result to auto-fill brand, model, reference, year, and market price. If a photo is available, it is downloaded and attached automatically. The feature degrades gracefully if Chrono24 is unreachable.
83118

84-
### Inline Editing
85-
Flips and collection watches can be edited directly **inline in the list table** without navigating to a separate page, keeping the workflow fast.
119+
When adding a new flip or collection watch, a **Chrono24 search** field appears at the top of the form. Type a brand, model, or reference number and select a result to auto-fill brand, model, reference, year, and market price. If a photo is available, it is downloaded and attached automatically. Search is debounced (500 ms) and results are cached per session. The feature degrades gracefully if Chrono24 is unreachable.
120+
121+
---
122+
123+
### Inline Editing & Sorting
124+
125+
Flips and collection watches can be edited directly **inline in the list table** without navigating to a separate page, keeping the workflow fast. All tables support **clickable column headers** for sorting — ascending/descending toggle with smart type detection: numeric, date (all three common formats), and text. Destructive actions use an **inline Yes/No confirmation popover** that auto-dismisses after 5 seconds, avoiding disruptive modal dialogs.
126+
127+
---
128+
129+
### Dark Mode
130+
131+
A built-in **light/dark theme toggle** is available from every page. Your preference is saved to localStorage and applied immediately on load — no flash of unstyled content.
132+
133+
---
86134

87135
### Export / Import
88-
Full backup and restore from Settings or Dashboard. The export is a **ZIP archive** containing `data.json` (all tables) plus the `images/` directory. Import accepts both the new ZIP format and the legacy plain-JSON format.
136+
137+
Full backup and restore from Settings or Dashboard. The export is a **ZIP archive** containing `data.json` (all tables) plus the `images/` directory. Import accepts both the new ZIP format and the legacy plain-JSON format. ZIP files are detected automatically by magic bytes — no extension guessing.
138+
139+
---
89140

90141
### Internationalisation
91-
UI language is switchable from Settings. Translations live in `lang/en.json` and are also available in Italian, German, French, and Spanish (`lang/it.json`, `de.json`, `fr.json`, `es.json`).
142+
143+
UI language is switchable from Settings. Translations live in `lang/en.json` and are also available in Italian, German, French, and Spanish (`lang/it.json`, `de.json`, `fr.json`, `es.json`). Number formatting adapts to locale (e.g. Italian `1.234,56` vs. standard `1234.56`).
92144

93145
---
94146

0 commit comments

Comments
 (0)