|
1 | 1 | # Developing Stonks Overwatch |
2 | 2 |
|
3 | | -Stonks Overwatch is a portfolio tracker integrating with multiple brokers (DeGiro, Bitvavo, IBKR) using a **unified modern architecture** (2025). The system features factory patterns, dependency injection, interface-based design, and a centralized broker registry that dramatically simplifies development and maintenance. |
| 3 | +Stonks Overwatch is a portfolio tracker integrating with multiple brokers (DeGiro, Bitvavo, IBKR) using a |
| 4 | +**unified modern architecture** (2025). The system features factory patterns, dependency injection, |
| 5 | +interface-based design, and a centralized broker registry that dramatically simplifies development and maintenance. |
4 | 6 |
|
5 | 7 | ## First Steps |
6 | 8 |
|
@@ -151,7 +153,7 @@ for broker in ["degiro", "bitvavo", "ibkr"]: |
151 | 153 | print(f"❌ {broker} {service_type.value}: {e}") |
152 | 154 | ``` |
153 | 155 |
|
154 | | -The demo database can use used with `make run demo=true` |
| 156 | +The demo database can be used with `make run demo=true`. The application will automatically route all database operations to the demo database using the built-in database routing system. |
155 | 157 |
|
156 | 158 | ```shell |
157 | 159 | make briefcase-package |
@@ -232,15 +234,112 @@ The modern configuration supports multiple brokers: |
232 | 234 |
|
233 | 235 | ### Create a Demo Database |
234 | 236 |
|
| 237 | +The demo database allows users to explore the application features without connecting to real broker accounts. It contains synthetic transaction data and market information for demonstration purposes. |
| 238 | +
|
| 239 | +#### For Developers: Generating the Demo Database |
| 240 | +
|
| 241 | +To regenerate the demo database from scratch: |
| 242 | +
|
| 243 | +```shell |
| 244 | +poetry run python -m scripts.generate_demo_db \ |
| 245 | + --start-date "2024-01-01" \ |
| 246 | + --num-transactions 150 \ |
| 247 | + --initial-deposit 10000 \ |
| 248 | + --monthly-deposit 500 |
| 249 | +``` |
| 250 | +
|
| 251 | +This command will: |
| 252 | +1. Create a fresh demo database with synthetic transaction data |
| 253 | +2. Generate realistic market data for popular stocks and ETFs |
| 254 | +3. Copy the database to `src/stonks_overwatch/fixtures/demo_db.sqlite3` for bundling with Briefcase distributions |
| 255 | +4. The bundled template should be committed to version control |
| 256 | +
|
| 257 | +For more details on available parameters: |
| 258 | +
|
235 | 259 | ```shell |
236 | | -poetry run python ./scripts/generate_demo_db.py --help |
| 260 | +poetry run python -m scripts.generate_demo_db --help |
237 | 261 | ``` |
238 | 262 |
|
239 | | -This command will create a demo database with sample data for multiple brokers. It is useful for testing purposes or to showcase the application without needing real broker accounts. |
| 263 | +> **Important**: After generating a new demo database, commit the updated `src/stonks_overwatch/fixtures/demo_db.sqlite3` file to git. This ensures the latest demo data is bundled with all distributions. |
| 264 | +
|
| 265 | +#### For Users: Demo Mode in the Native App |
| 266 | +
|
| 267 | +When users activate demo mode via the application menu: |
| 268 | +1. The application checks if a demo database exists in the user's data directory |
| 269 | +2. If the bundled demo database is different (detected by comparing SHA256 hashes): |
| 270 | + - The existing demo database is backed up to `demo_db.sqlite3.backup` |
| 271 | + - The new demo database is copied from the application bundle |
| 272 | + - This ensures users always get the latest demo data after app updates |
| 273 | +3. The application switches to demo mode and applies any pending migrations |
| 274 | +4. All broker API connections are disabled in demo mode |
| 275 | +
|
| 276 | +The demo database is distributed as a pre-populated SQLite file (approximately 384KB), providing instant access to demo features. |
| 277 | +
|
| 278 | +> **Note**: When updating the application to a new version with updated demo data, the old demo database is automatically backed up. Users' actual portfolio data in the production database is never affected by demo mode operations. |
| 279 | +
|
| 280 | +#### Demo Database Location |
| 281 | +
|
| 282 | +- **Bundled template**: `src/stonks_overwatch/fixtures/demo_db.sqlite3` (read-only, in git) |
| 283 | +- **User's working copy**: `$STONKS_OVERWATCH_DATA_DIR/demo_db.sqlite3` (created on first demo activation) |
| 284 | +
|
| 285 | +The demo database can be used with `make run demo=true`. The application will automatically route all database operations to the demo database using the built-in database routing system. |
| 286 | +
|
| 287 | +### Demo Mode Database Routing |
| 288 | +
|
| 289 | +The application features an advanced database routing system that allows seamless switching between production and demo databases without requiring server restarts. |
| 290 | +
|
| 291 | +#### How It Works |
| 292 | +
|
| 293 | +The application supports two database configurations: |
| 294 | +- **Production Database** (`db.sqlite3`): Contains real user data |
| 295 | +- **Demo Database** (`demo_db.sqlite3`): Contains demo/sample data for testing |
240 | 296 |
|
241 | | -> This script expects the `config/config.json` file to be present and properly configured. |
| 297 | +The `DatabaseRouter` class automatically routes all database operations to the appropriate database based on the `DEMO_MODE` environment variable: |
| 298 | +
|
| 299 | +- When `DEMO_MODE=False` (or unset): Routes to the production database |
| 300 | +- When `DEMO_MODE=True`: Routes to the demo database |
| 301 | +
|
| 302 | +#### Database Configuration |
| 303 | +
|
| 304 | +Both databases are defined in `settings.py`: |
| 305 | +
|
| 306 | +```python |
| 307 | +DATABASES = { |
| 308 | + "default": { |
| 309 | + "ENGINE": "django.db.backends.sqlite3", |
| 310 | + "NAME": Path(STONKS_OVERWATCH_DATA_DIR).resolve().joinpath("db.sqlite3"), |
| 311 | + # ... production database settings |
| 312 | + }, |
| 313 | + "demo": { |
| 314 | + "ENGINE": "django.db.backends.sqlite3", |
| 315 | + "NAME": Path(STONKS_OVERWATCH_DATA_DIR).resolve().joinpath("demo_db.sqlite3"), |
| 316 | + # ... demo database settings |
| 317 | + }, |
| 318 | +} |
| 319 | +
|
| 320 | +DATABASE_ROUTERS = ["stonks_overwatch.utils.database.db_router.DatabaseRouter"] |
| 321 | +``` |
| 322 | +
|
| 323 | +#### Benefits of Database Routing |
| 324 | +
|
| 325 | +1. **No Server Restart Required**: Database switching happens instantly |
| 326 | +2. **Data Isolation**: Production and demo data are completely separate |
| 327 | +3. **Transparent Operation**: All existing code works without modification |
| 328 | +4. **Consistent Schema**: Both databases maintain the same structure through migrations |
| 329 | +
|
| 330 | +#### Migration Handling |
| 331 | +
|
| 332 | +Both databases support migrations independently: |
| 333 | +
|
| 334 | +```shell |
| 335 | +# Apply migrations to production database |
| 336 | +python manage.py migrate --database=default |
| 337 | +
|
| 338 | +# Apply migrations to demo database |
| 339 | +python manage.py migrate --database=demo |
| 340 | +``` |
242 | 341 |
|
243 | | -The demo database can be used with `make run demo=true` |
| 342 | +The router ensures migrations can be applied to both databases as needed, maintaining schema consistency. |
244 | 343 |
|
245 | 344 | ## Dump and Load a Database |
246 | 345 |
|
@@ -275,7 +374,7 @@ Example configuration to enable offline mode for multiple brokers: |
275 | 374 | } |
276 | 375 | ``` |
277 | 376 |
|
278 | | -The offline mode can be used together with `demo=true` to load the demo database and run the application without any external API calls. |
| 377 | +The offline mode can be used together with `demo=true` to load the demo database and run the application without any external API calls. The database routing system ensures that demo data is completely isolated from production data, making it safe to experiment with different configurations. |
279 | 378 |
|
280 | 379 | ### Broker-Specific Development |
281 | 380 |
|
|
0 commit comments