Backend API¶
Application¶
main ¶
Main FastAPI Application Desktop-only backend API for Google Calendar integrated masterplan optimisation.
validation_exception_handler
async
¶
Return a sanitized validation error response for malformed requests.
Source code in backend/app/main.py
check_desktop_token
async
¶
Require Electron's per-launch desktop token for non-exempt routes.
Source code in backend/app/main.py
limit_request_body
async
¶
Reject oversized local API requests before they reach route handlers.
Source code in backend/app/main.py
health_check
async
¶
Liveness / readiness probe.
Source code in backend/app/main.py
startup_event
async
¶
Initialise a current-schema database without compatibility migrations.
Source code in backend/app/main.py
App Settings¶
app_settings ¶
App Settings API Endpoints Manages application-wide configuration like Google OAuth credentials and solver tuning parameters.
SolverSettingsPayload ¶
Bases: BaseModel
Writable solver tuning values supplied by the settings UI.
Source code in backend/app/api/v1/app_settings.py
SolverSettingsResponse ¶
Bases: BaseModel
Solver tuning values returned to the frontend.
Source code in backend/app/api/v1/app_settings.py
GoogleOAuthPayload ¶
GoogleOAuthStatus ¶
Bases: BaseModel
Configuration status for locally stored Google OAuth credentials.
Source code in backend/app/api/v1/app_settings.py
PublishTargetPayload ¶
Bases: BaseModel
Requested publish target for schedule export actions.
Source code in backend/app/api/v1/app_settings.py
PublishTargetResponse ¶
ShortcutSettingsPayload ¶
Bases: BaseModel
Keyboard shortcut override map keyed by frontend shortcut id.
Source code in backend/app/api/v1/app_settings.py
ShortcutSettingsResponse ¶
get_solver_settings ¶
Read solver settings from AppSettings table, falling back to defaults.
Source code in backend/app/api/v1/app_settings.py
get_solver_settings_endpoint
async
¶
Get current solver tuning parameters.
Source code in backend/app/api/v1/app_settings.py
set_solver_settings
async
¶
Save solver tuning parameters.
Source code in backend/app/api/v1/app_settings.py
reset_solver_settings
async
¶
Reset solver parameters to defaults.
Source code in backend/app/api/v1/app_settings.py
get_google_oauth_status
async
¶
Check whether Google OAuth credentials are configured.
Source code in backend/app/api/v1/app_settings.py
set_google_oauth
async
¶
Save or update Google OAuth credentials.
Source code in backend/app/api/v1/app_settings.py
delete_google_oauth
async
¶
Remove stored Google OAuth credentials.
Source code in backend/app/api/v1/app_settings.py
get_publish_target
async
¶
Get the current publish target. Defaults to 'none'.
Source code in backend/app/api/v1/app_settings.py
set_publish_target
async
¶
Set the publish target.
Source code in backend/app/api/v1/app_settings.py
get_shortcuts
async
¶
Get keyboard shortcut overrides. Defaults are held by the frontend.
Source code in backend/app/api/v1/app_settings.py
set_shortcuts
async
¶
Save keyboard shortcut overrides.
Source code in backend/app/api/v1/app_settings.py
reset_shortcuts
async
¶
Clear keyboard shortcut overrides.
Source code in backend/app/api/v1/app_settings.py
Data Management¶
data_management ¶
Data Management API - export, import, copy-from-event, delete-event, factory-reset.
ExportRequest ¶
Bases: BaseModel
Data export request selecting full, global-only, or event-only scope.
Source code in backend/app/api/v1/data_management.py
ImportRequest ¶
ImportValidationIssue ¶
Bases: BaseModel
Structured import validation message shown before import.
Source code in backend/app/api/v1/data_management.py
ImportPreviewSummary ¶
Bases: BaseModel
Human-readable import contents summary.
Source code in backend/app/api/v1/data_management.py
ImportValidationResult ¶
Bases: BaseModel
Validation result used by the import preview UI.
Source code in backend/app/api/v1/data_management.py
CopyFromEventRequest ¶
Bases: BaseModel
Request to copy selected setup data from one event into another.
Source code in backend/app/api/v1/data_management.py
CopiedTaskDateRepairRequest ¶
Bases: BaseModel
Identify a source and target event for copied task-date repair.
Source code in backend/app/api/v1/data_management.py
ApplyCopiedTaskDateRepairRequest ¶
Bases: CopiedTaskDateRepairRequest
Apply the selected copied task-date repairs after revalidation.
Source code in backend/app/api/v1/data_management.py
CopiedTaskDateRepairCandidate ¶
Bases: BaseModel
One copied task skeleton and its proposed target-event date.
Source code in backend/app/api/v1/data_management.py
CopiedTaskDateRepairPreview ¶
Bases: BaseModel
Preview of safe copied task-date repairs for one event pair.
Source code in backend/app/api/v1/data_management.py
TaskDateMappingError ¶
FactoryResetRequest ¶
export_data
async
¶
Export data as JSON.
scope=full → global settings + all events (type="full_backup") scope=global → global settings only (type="app_settings") scope=event → global settings + 1+ events (type="project")
Source code in backend/app/api/v1/data_management.py
validate_import_payload ¶
Validate an import payload and build a preview without mutating data.
Source code in backend/app/api/v1/data_management.py
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | |
preview_import_data
async
¶
Validate an import payload and return a safe preview summary.
import_data
async
¶
Import data from a previously exported JSON payload.
The file always contains global_data (always imported first). Events are imported after global data, with FK remapping.
Source code in backend/app/api/v1/data_management.py
copy_from_event
async
¶
Clone selected data from one event into another (internal DB copy).
Source code in backend/app/api/v1/data_management.py
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 | |
preview_copied_task_date_repair
async
¶
Preview safe date repairs for task skeletons copied between events.
Source code in backend/app/api/v1/data_management.py
apply_copied_task_date_repair
async
¶
Apply selected copied task-date repairs after revalidating the preview.
Source code in backend/app/api/v1/data_management.py
delete_event
async
¶
Delete a single event and all its scoped data.
Source code in backend/app/api/v1/data_management.py
factory_reset
async
¶
Wipe ALL data and recreate default theme. Requires confirmation='RESET'.
Source code in backend/app/api/v1/data_management.py
2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 | |
Events¶
events ¶
Events API Endpoints
EventCreate ¶
Bases: BaseModel
Payload for creating or replacing an event record.
Source code in backend/app/api/v1/events.py
EventCalendarUpdate ¶
PdfExportSettingsUpdate ¶
EnabledCapabilitiesUpdate ¶
get_events
async
¶
get_event
async
¶
Get a specific event
Source code in backend/app/api/v1/events.py
create_event
async
¶
Create a new event
Source code in backend/app/api/v1/events.py
update_event
async
¶
Update an existing event
Source code in backend/app/api/v1/events.py
update_event_calendar
async
¶
Update only the Google Calendar ID on an event.
Source code in backend/app/api/v1/events.py
delete_event
async
¶
Delete an event and all associated data.
Source code in backend/app/api/v1/events.py
update_event_status
async
¶
Update an event's status (draft | optimised | finalised | published).
Source code in backend/app/api/v1/events.py
update_event_capabilities
async
¶
update_event_capabilities(event_id: int, data: EnabledCapabilitiesUpdate, db: Session = Depends(get_db))
Update the enabled capabilities for an event. null = all enabled.
Source code in backend/app/api/v1/events.py
Google Publishing¶
google ¶
Google Calendar API Endpoints Handles OAuth2 connection, calendar selection, and publishing to Google Calendar.
ConnectResponse ¶
OAuthCallbackRequest ¶
ConnectionResponse ¶
Bases: BaseModel
Stored Google Calendar account connection exposed to the frontend.
Source code in backend/app/api/v1/google.py
CalendarInfo ¶
Bases: BaseModel
Calendar metadata returned by the Google Calendar API.
Source code in backend/app/api/v1/google.py
CalendarMember ¶
SetCalendarRequest ¶
PublishRequest ¶
Bases: BaseModel
Google Calendar publish request for one event and optional date subset.
Source code in backend/app/api/v1/google.py
PublishDayResult ¶
PublishResponse ¶
get_connections
async
¶
Get all Google Calendar connections.
Source code in backend/app/api/v1/google.py
start_connect
async
¶
Start OAuth2 flow - returns the Google authorisation URL.
Source code in backend/app/api/v1/google.py
oauth2_callback_redirect
async
¶
GET handler for the Google OAuth2 redirect. Serves a small HTML page that posts the authorisation code back to the opener (Electron / browser) window via postMessage, then closes itself.
Source code in backend/app/api/v1/google.py
oauth2_callback
async
¶
Exchange authorisation code for tokens and store the connection.
Source code in backend/app/api/v1/google.py
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | |
disconnect
async
¶
Remove a Google Calendar connection.
Source code in backend/app/api/v1/google.py
get_calendars
async
¶
List all calendars for a Google account connection.
Source code in backend/app/api/v1/google.py
get_calendar_members
async
¶
get_calendar_members(connection_id: int = Query(...), calendar_id: str = Query(...), db: Session = Depends(get_db))
List people who have access to a specific calendar.
Source code in backend/app/api/v1/google.py
set_calendar
async
¶
Set the selected calendar for a connection.
Source code in backend/app/api/v1/google.py
get_calendar_colors
async
¶
Fetch available event colours from Google Calendar API.
Source code in backend/app/api/v1/google.py
publish_to_calendar
async
¶
Publish tasks to Google Calendar. If dates are specified, publish only those days. Otherwise, publish all days of the event. Deletes existing events for each day before writing.
Source code in backend/app/api/v1/google.py
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | |
Encryption¶
encryption ¶
Column-level encryption for sensitive data stored in the local SQLite database. Uses Fernet (AES-128-CBC + HMAC-SHA256) via the cryptography library.
The encryption key is generated once and stored alongside the active database. Packaged desktop builds pass ENCRYPTION_KEY_PATH so updates keep the key in Electron's stable user-data directory. The key is NOT checked into version control.
EncryptedJSON ¶
Bases: TypeDecorator
Transparently encrypts a dict/JSON value at rest in a TEXT column.
Source code in backend/app/core/encryption.py
EncryptedString ¶
Bases: TypeDecorator
Transparently encrypts a string value at rest in a TEXT column.
Source code in backend/app/core/encryption.py
encrypt_json ¶
Encrypt a dict as a Fernet-encrypted JSON string.
Source code in backend/app/core/encryption.py
decrypt_json ¶
Decrypt a current Fernet-encrypted JSON value.
Source code in backend/app/core/encryption.py
encrypt_str ¶
Encrypt a plain string.
decrypt_str ¶
Decrypt a current Fernet-encrypted string.
Source code in backend/app/core/encryption.py
Google Calendar Service¶
google_calendar_service ¶
Google Calendar Service Handles OAuth2 authentication, calendar listing, and publishing tasks to Google Calendar.
create_auth_url ¶
Create an OAuth2 authorisation URL. Returns (auth_url, state) tuple.
Source code in backend/app/core/google_calendar_service.py
exchange_code_for_token ¶
Exchange an authorisation code for tokens. Returns token data dict (access_token, refresh_token, etc.).
Source code in backend/app/core/google_calendar_service.py
list_calendars ¶
List all calendars accessible to the authenticated user.
Source code in backend/app/core/google_calendar_service.py
list_calendar_members ¶
list_calendar_members(token_data: dict, calendar_id: str, on_token_update=None) -> List[Dict[str, str]]
List people who have access to a calendar (ACL entries with email).
Source code in backend/app/core/google_calendar_service.py
get_event_colors ¶
Fetch available event colours from Google Calendar API.
Source code in backend/app/core/google_calendar_service.py
publish_day_to_calendar ¶
publish_day_to_calendar(token_data: dict, calendar_id: str, target_date: date, tasks: List[Dict[str, Any]], persons_by_id: Dict[int, Dict[str, Any]], locations_by_id: Dict[int, Dict[str, Any]], export_formats: Optional[Dict[int, Dict[str, Any]]] = None, task_types_by_id: Optional[Dict[int, Dict[str, Any]]] = None, templates_by_id: Optional[Dict[int, Dict[str, Any]]] = None, on_token_update=None) -> Dict[str, Any]
Publish tasks for a single day to Google Calendar. 1. Delete all events for target_date in this calendar 2. Create new events from tasks
Returns summary of created/deleted events.
Source code in backend/app/core/google_calendar_service.py
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 | |
Optimisation Runner¶
optimization_runner ¶
Background Optimisation Task Runner Handles the actual execution of optimisation in background threads
run_optimization_background ¶
run_optimization_background(job_id: int, normalized_input: Dict[str, Any], test_mode: bool = False) -> None
Execute optimisation in background thread.
This function: 1. Updates job status to "running" 2. Calls compute service with real optimiser 3. Writes results to task.optimised and Assignment records 4. Updates job with results or error 5. Handles all exceptions gracefully
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
job_id
|
int
|
ID of the OptimizationJob record |
required |
normalized_input
|
Dict[str, Any]
|
Normalised data ready for compute service |
required |
test_mode
|
bool
|
Ignored - always uses real optimiser |
False
|
Source code in backend/app/core/optimization_runner.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
call_compute_service_sync ¶
call_compute_service_sync(normalized_input: Dict[str, Any], request_id: str = None) -> Dict[str, Any]
Synchronous call to compute service.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalized_input
|
Dict[str, Any]
|
Dictionary with tasks, persons, transfers, etc. |
required |
request_id
|
str
|
Optional UUID for progress tracking on compute side. |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
Dictionary with optimisation results |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If compute service call fails |