Complete reference for service interfaces, models, and enumerations.
WinWork uses a dependency-injected service layer. All services are registered via ServiceCollectionExtensions and consumed through constructor injection.
Main service for link CRUD and tree operations.
public interface ILinkService
{
Task<IEnumerable<Link>> GetAllLinksAsync();
Task<Link?> GetLinkAsync(int id);
Task<IEnumerable<Link>> GetRootLinksAsync();
Task<IEnumerable<Link>> GetChildLinksAsync(int parentId);
Task<Link> CreateLinkAsync(Link link);
Task<Link> UpdateLinkAsync(Link link);
Task<bool> MoveLinkAsync(int linkId, int? newParentId, int newSortOrder);
Task<Link> DuplicateLinkAsync(int linkId, int? newParentId);
Task<int> GetMaxSortOrderAsync(int? parentId);
Task<List<(string Name, LinkType Type)>> DeleteLinkRecursiveAsync(int id);
Task<bool> ValidateLinkAsync(Link link);
Task OpenLinkAsync(int linkId);
Task<IEnumerable<Link>> SearchLinksAsync(string searchTerm);
Task<bool> DeleteLinkAsync(int id);
Task<IEnumerable<Link>> GetStartupEnabledLinksAsync();
}| Method | Description |
|---|---|
GetAllLinksAsync |
Returns all links in the database |
GetRootLinksAsync |
Returns only top-level (parentless) links |
GetChildLinksAsync |
Returns children of a given parent ID |
MoveLinkAsync |
Moves a link to a new parent with sort order |
DuplicateLinkAsync |
Deep-copies a link (and, for folders, its whole subtree) under a new parent |
DeleteLinkRecursiveAsync |
Deletes a link and all descendants, returns list of deleted items |
SearchLinksAsync |
Full-text search across Name, URL, Description, Notes |
GetStartupEnabledLinksAsync |
Returns links with IsWinStartEnabled = true for auto-launch |
Tag management with link-tag associations.
public interface ITagService
{
Task<IEnumerable<Tag>> GetAllTagsAsync();
Task<Tag?> GetTagAsync(int id);
Task<Tag?> GetTagByNameAsync(string name);
Task<IEnumerable<Tag>> SearchTagsAsync(string searchTerm);
Task<IEnumerable<Tag>> GetTagsForLinkAsync(int linkId);
Task<Tag> CreateTagAsync(Tag tag);
Task<Tag> UpdateTagAsync(Tag tag);
Task<bool> DeleteTagAsync(int id);
Task<bool> AddTagToLinkAsync(int linkId, int tagId);
Task<bool> RemoveTagFromLinkAsync(int linkId, int tagId);
Task<bool> ValidateTagAsync(Tag tag);
}Opens links using the appropriate handler based on LinkType. Raises events for types that require UI interaction.
public interface ILinkOpenerService
{
event EventHandler<NotesOpenRequestEventArgs>? NotesOpenRequested;
event EventHandler<WebViewOpenRequestEventArgs>? WebViewOpenRequested;
event EventHandler<SlideshowOpenRequestEventArgs>? SlideshowOpenRequested;
event EventHandler<StickyNoteOpenRequestEventArgs>? StickyNoteOpenRequested;
Task<bool> OpenAsync(Link link);
Task<bool> OpenAsync(string url, LinkType type);
bool CanOpen(LinkType type);
bool ValidateLink(string url, LinkType type);
}Events:
NotesOpenRequested— Fires when a Notes link is opened (needs Notes editor UI)WebViewOpenRequested— Fires when a WebView link is opened (needs WebView window)SlideshowOpenRequested— Fires when a Slideshow link is opened (needs Slideshow window with config)StickyNoteOpenRequested— Fires when a Sticky Note link is opened (needs StickyNoteWindow)
Activity logging and notification management.
public interface INotificationService
{
Task<Notification> LogAsync(string title, string message, int notificationType, int? linkId = null, string? status = null);
Task<IEnumerable<Notification>> GetRecentAsync(int count = 50);
Task<int> GetUnreadCountAsync();
Task MarkReadAsync(int id);
Task MarkAllReadAsync();
Task DeleteAsync(int id);
Task ClearAsync();
}Notification Types: 0 = Info, 1 = Success, 2 = Warning, 3 = Error
Manages Hot Navigation panels (quick-access link groups).
public interface IHotNavService
{
Task<IEnumerable<HotNav>> GetAllAsync();
Task<HotNav?> GetByIdAsync(int id);
Task<HotNav> CreateAsync(HotNav hotNav);
Task<HotNav> UpdateAsync(HotNav hotNav);
Task<bool> DeleteAsync(int id);
}Import from browsers and export to multiple formats.
public interface IImportExportService
{
// Import from browsers
Task<IEnumerable<Link>> ImportChromeBookmarksAsync(string filePath);
Task<IEnumerable<Link>> ImportFirefoxBookmarksAsync(string filePath);
Task<IEnumerable<Link>> ImportEdgeBookmarksAsync(string filePath);
Task<IEnumerable<Link>> ImportFromJsonAsync(string filePath);
// Export
Task<bool> ExportToJsonAsync(IEnumerable<Link> links, string filePath);
Task<bool> ExportToHtmlAsync(IEnumerable<Link> links, string filePath);
Task<bool> ExportToCsvAsync(IEnumerable<Link> links, string filePath);
}Modal dialog abstraction for WPF MessageBox/InputBox patterns.
public interface IModalService
{
Task ShowModalAsync(string title, string message);
Task<ModalResult> ShowModalAsync(string title, string message, ModalButtons buttons, ModalIcon icon = ModalIcon.Information);
Task<string?> ShowInputAsync(string prompt, string defaultValue = "", string placeholder = "");
string? ShowInputDialog(string prompt, string title = "Input");
}Enums: ModalResult (None, Ok, Cancel, Yes, No), ModalButtons (Ok, OkCancel, YesNo, YesNoCancel), ModalIcon (None, Information, Warning, Error, Question)
Windows toast/balloon notifications for reminders.
public interface IToastService : IDisposable
{
void ShowReminder(string title, string message, int notificationType = 0);
void SetCustomNotificationHandler(Action<string, string> handler);
}Registers Windows global hotkeys using Win32 API.
public interface IGlobalHotkeysService
{
event EventHandler<string>? HotKeyPressed;
bool RegisterHotKey(string name, Keys key, ModifierKeys modifiers);
bool UnregisterHotKey(string name);
void UnregisterAllHotKeys();
bool IsHotKeyRegistered(string name);
IEnumerable<string> GetRegisteredHotKeyNames();
}ModifierKeys Flags: None = 0, Alt = 1, Control = 2, Shift = 4, Windows = 8
System tray icon with context menu and balloon tips.
public interface ISystemTrayService
{
event EventHandler? ShowMainWindow;
event EventHandler? ExitApplication;
void Initialize(string applicationName, Icon? icon = null);
void Show();
void Hide();
void ShowBalloonTip(string title, string text, ToolTipIcon icon = ToolTipIcon.Info, int timeout = 3000);
void UpdateIcon(Icon icon);
void UpdateText(string text);
bool IsVisible { get; }
}Model Context Protocol server for AI assistant integration.
public interface IMcpServerService
{
bool IsRunning { get; }
Task StartAsync(string host, int port, string apiKey, bool useHttps = false, string? certPath = null, string? certPassword = null);
Task StopAsync();
string GenerateApiKey();
}Controls the storage mode (local, remote, or hybrid sync).
public interface IStorageConfiguration
{
StorageMode CurrentMode { get; }
string? ApiBaseUrl { get; }
string? ApiUsername { get; }
string? ApiPassword { get; }
string? ClientId { get; }
bool AutoSyncEnabled { get; }
int AutoSyncIntervalSeconds { get; }
bool UsesLocalStorage { get; } // true for LocalOnly, LocalWithSync
bool UsesRemoteApi { get; } // true for RemoteOnly, LocalWithSync
bool IsSyncMode { get; } // true for LocalWithSync only
Task SetModeAsync(StorageMode mode);
Task SetApiConfigAsync(string baseUrl, string username, string password);
Task SetAutoSyncAsync(bool enabled, int intervalSeconds = 300);
}StorageMode Enum:
| Value | Name | Description |
|---|---|---|
| 0 | LocalOnly |
Pure offline — all data in local SQLite |
| 1 | RemoteOnly |
All CRUD goes directly to the remote API |
| 2 | LocalWithSync |
Hybrid — local SQLite + bidirectional sync with API |
Bidirectional sync between local SQLite and remote API with conflict resolution.
public interface ISyncService
{
bool IsSyncing { get; }
DateTime? LastSyncTime { get; }
event EventHandler<SyncResultEventArgs>? SyncCompleted;
event EventHandler<SyncConflictEventArgs>? ConflictDetected;
Task<SyncResult> PushChangesAsync();
Task<SyncResult> PullChangesAsync();
Task<SyncResult> SyncAsync(); // Full bidirectional: push → pull
Task<SyncResult> FullUploadAsync(); // Initial full export to server
Task<SyncResult> FullDownloadAsync(); // Initial full import from server
Task ResolveConflictAsync(SyncConflict conflict, ConflictResolution resolution, object? mergedData = null);
Task<SyncStatusSummary> GetSyncStatusAsync();
void StartAutoSync(int intervalSeconds = 300);
void StopAutoSync();
Task MarkDirtyAsync(string entityType, int localId, string action = "update");
Task<List<SyncConflict>> GetPendingConflictsAsync();
}ConflictResolution Enum: KeepServer, KeepClient, Merge, SaveAsCopy
HTTP client for the WinWork remote API with JWT authentication.
public interface IRemoteApiClient
{
bool IsAuthenticated { get; }
Task<bool> LoginAsync(string username, string password);
Task<ApiConnectionResult> TestConnectionAsync(string baseUrl, string? username = null, string? password = null);
Task<ApiResponse<T>> GetAsync<T>(string endpoint);
Task<ApiResponse<T>> PostAsync<T>(string endpoint, object? body = null);
Task<ApiResponse<T>> PutAsync<T>(string endpoint, object? body = null);
Task<ApiResponse<T>> DeleteAsync<T>(string endpoint);
Task<ApiResponse<JsonElement>> PostJsonAsync(string endpoint, object? body = null);
Task<ApiResponse<JsonElement>> GetJsonAsync(string endpoint);
void SetBaseUrl(string baseUrl);
}Manages workflow apps — CRUD, execution, versioning.
public interface IAppService
{
// CRUD
Task<App> GetAppAsync(int id);
Task<IEnumerable<App>> GetAllAppsAsync();
Task<IEnumerable<App>> GetMenuAppsAsync();
Task<IEnumerable<App>> GetServiceAppsAsync();
Task<App> CreateAppAsync(App app);
Task<App> UpdateAppAsync(App app);
Task DeleteAppAsync(int id);
// Execution
Task<AppExecutionResult> ExecuteAppAsync(
int appId,
Dictionary<string, object>? initialVariables = null,
int? parentExecutionId = null,
CancellationToken cancellationToken = default);
// History
Task<IEnumerable<AppExecutionLog>> GetExecutionHistoryAsync(int appId, int limit = 100);
// Versioning
Task<AppVersion> PublishAppAsync(int appId, string? releaseNotes = null);
Task<IEnumerable<AppVersion>> GetAppVersionsAsync(int appId);
Task RestoreAppVersionAsync(int appId, int versionNumber);
}Manages steps and connections within a workflow.
public interface IAppStepService
{
Task<AppStep> GetStepAsync(int id);
Task<IEnumerable<AppStep>> GetAppStepsAsync(int appId);
Task<AppStep> CreateStepAsync(AppStep step);
Task<AppStep> UpdateStepAsync(AppStep step);
Task DeleteStepAsync(int id);
// Connections between steps
Task<StepConnection> CreateConnectionAsync(StepConnection connection);
Task DeleteConnectionAsync(int id);
Task<IEnumerable<StepConnection>> GetAppConnectionsAsync(int appId);
}Manages triggers that start workflow execution.
public interface IAppTriggerService
{
Task<List<AppTrigger>> GetTriggersAsync(int appId);
Task<List<AppTrigger>> GetActiveCronTriggersAsync();
Task<List<AppTrigger>> GetStartupTriggersAsync();
Task<AppTrigger?> GetTriggerAsync(int triggerId);
Task<AppTrigger> CreateTriggerAsync(AppTrigger trigger);
Task<bool> UpdateTriggerAsync(AppTrigger trigger);
Task<bool> DeleteTriggerAsync(int triggerId);
Task<bool> EnableTriggerAsync(int triggerId, bool enabled);
}Trigger Types: Manual, Cron schedule, App startup, Webhook
Cron expression parsing and scheduled app execution.
public interface ICronSchedulerService
{
bool IsValidCronExpression(string cronExpression);
DateTime? GetNextOccurrence(string cronExpression);
void ScheduleApp(int triggerId, int appId, string cronExpression);
void UnscheduleApp(int triggerId);
Task StartSchedulerAsync();
void StopScheduler();
}Manages the registry of available component types.
public interface IComponentTypeService
{
Task<ComponentType> GetComponentTypeAsync(int id);
Task<ComponentType?> GetComponentByNameAsync(string name);
Task<IEnumerable<ComponentType>> GetAllComponentTypesAsync();
Task<IEnumerable<ComponentType>> GetComponentTypesByCategoryAsync(string category);
Task<ComponentType> CreateComponentTypeAsync(ComponentType componentType);
Task<ComponentType> UpdateComponentTypeAsync(ComponentType componentType);
Task DeleteComponentTypeAsync(int id);
IAppComponent GetComponentExecutor(string executorClass);
}There are currently 48 component types across categories: Logic, DataSource, Action, Input, String, Array, Variable.
Manages reusable, shareable component instances with versioning.
public interface IComponentInstanceService
{
Task<List<ComponentInstance>> GetAllAsync();
Task<ComponentInstance?> GetByIdAsync(int id);
Task<ComponentInstance> CreateAsync(int componentTypeId, string name, string description, string configuration, string icon, string color);
Task<ComponentInstance> UpdateAsync(int id, string name, string description, string configuration);
Task<ComponentInstance> DuplicateAsync(int id, string newName);
Task<bool> IsNameUniqueAsync(string name, int? excludeId = null);
Task<string> GetNextAvailableNameAsync(string baseName);
Task<int> GetUsageCountAsync(int id);
Task<int> DeleteAsync(int id, bool convertToIndependent);
Task ConvertToIndependentAsync(int appStepId);
Task<List<InstanceVersion>> GetVersionHistoryAsync(int instanceId);
Task<ComponentInstance> RollbackToVersionAsync(int instanceId, int targetVersionId, string? changeNotes = null);
Task<InstanceVersion?> GetVersionAsync(int versionId);
}Interface implemented by all 48 workflow component executors.
public interface IAppComponent
{
Task<Dictionary<string, object>> ExecuteAsync(
Dictionary<string, object> inputs,
string configuration,
CancellationToken cancellationToken = default);
}Each component receives inputs (variables from previous steps) and configuration (JSON), and returns output variables for downstream steps.
The primary entity representing all items in the hierarchical tree.
public class Link
{
public int Id { get; set; }
public string Name { get; set; }
public string? Url { get; set; }
public LinkType Type { get; set; }
public string? Command { get; set; } // Terminal commands
public string? TerminalType { get; set; } // Shell profile (PowerShell, Git Bash, CMD)
public string? CronSchedule { get; set; } // Cron expression for Terminal items
public bool EnableCronSchedule { get; set; }
public string? Description { get; set; }
public string? Notes { get; set; } // Content for Notes type
public int? ParentId { get; set; }
public int SortOrder { get; set; }
public string? IconPath { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public DateTime? LastAccessedAt { get; set; }
public int AccessCount { get; set; }
public bool IsExpanded { get; set; }
public bool IsSelected { get; set; }
public bool IsHotclick { get; set; } // Appears in Hotclicks panel
public bool IsWinStartEnabled { get; set; } // Auto-open on Windows start
// Time-type fields
public DateTime? StartAt { get; set; }
public DateTime? PreviousStartAt { get; set; }
public int RecurrenceKind { get; set; } // 0=None, 1=Hourly, 2=Daily, 3=Weekly, 4=Monthly, 5=Yearly
public int NotifyBeforeMinutes { get; set; }
public DateTime? SnoozedUntil { get; set; }
// Reminder fields (generic)
public bool EnableReminder { get; set; }
public int MinutesInterval { get; set; }
public int NotificationType { get; set; } // 0=Balloon, 1=Toast, 2=Custom, 3=Text-to-Speech
// Status (ToDo, Time)
public string? Status { get; set; } // Not Started, In Progress, Completed, On Hold
// System tray
public string TrayMenuPlacement { get; set; } // "", "MainMenu", "QuickLaunch"
// Menu / window placements (comma-separated: "Dock", etc.)
public string MenuPlacement { get; set; } // "", "Dock"
// Folder Path multi-open (comma-separated: Explorer, PowerShell, Git Bash, CMD)
public string? FolderOpenTargets { get; set; } // null/empty = Explorer only
// Slideshow
public string? SlideshowConfigJson { get; set; } // JSON-serialized SlideshowConfig
// Sticky Note appearance
public string? StickyNoteColor { get; set; } // Background hex (e.g., #FFFACD)
public string? StickyNoteFontColor { get; set; } // Font/text hex (e.g., #333311)
// Event Automation
public string? EventAutomationConfigJson { get; set; } // JSON-serialized EventAutomationConfig
// Favorites
public bool IsFavorite { get; set; }
// Navigation
public virtual Link? Parent { get; set; }
public virtual ICollection<Link> Children { get; set; }
public virtual ICollection<LinkTag> LinkTags { get; set; }
}public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; } // Hex color, e.g. "#FF5733"
public string? Description { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public virtual ICollection<LinkTag> LinkTags { get; set; }
}public enum LinkType
{
Folder = 0, // Container for other links
WebUrl = 1, // HTTP/HTTPS URL → opens in browser
FilePath = 2, // Local file → opens with default app
Application = 3, // Executable path → launches application
FolderPath = 4, // Directory path → Explorer and/or shells (FolderOpenTargets)
WindowsStoreApp = 5, // UWP app URI → launches Store app
SystemLocation = 6, // Control Panel / Settings URI
Notes = 7, // Rich-text notes (no URL required)
Terminal = 8, // Execute commands in PowerShell/Git Bash/CMD
Time = 9, // Deprecated — merged into ToDo (kept for back-compat)
ToDo = 10, // Task item with status tracking
WebView = 11, // Embedded mini browser window (WebView2)
Slideshow = 12, // Multi-panel URL slideshow with transitions
StickyNote = 13, // Floating sticky note with custom color/font
EventAutomation = 14, // Event monitor + response actions
WebService = 15, // Custom HTTP API calls
Terminals = 16, // Multi-session terminal workspace
Server = 17, // SSH / RDP connection details
Whiteboard = 18, // Excalidraw infinite canvas
Spreadsheet = 19 // Excel-like free-form grid (SpreadsheetConfigJson)
}Sparse grid: only non-empty cells are stored. Defaults: 26 columns × 50 rows per sheet.
public class SpreadsheetConfig
{
public List<SpreadsheetSheet> Sheets { get; set; }
public string? ActiveSheetId { get; set; }
// ToJson() / FromJson() / CreateDefault() / CompactEmptyCells()
// GetSearchText() / FindFirstMatch(query) / FindAllMatches(query)
}
public class SpreadsheetSheet
{
public string Id { get; set; }
public string Name { get; set; }
public List<SpreadsheetCell> Cells { get; set; } // { r, c, value } — 0-based
public int ColumnCount { get; set; } // default 26
public int RowCount { get; set; } // default 50
}Link.SpreadsheetSearchText is a denormalized plain-text index of cell values, regenerated on every spreadsheet save for SearchByNameAsync / global search. Opening a spreadsheet hit can pass SpreadsheetOpenContext { SheetId, Row, Col } so the window navigates to the matching cell.
public enum SlideshowLayout
{
FullScreen = 0,
TwoColumns = 1,
TwoRows = 2,
FourSquares = 3
}
public enum SlideTransition
{
None = 0,
Fade = 1,
SlideLeft = 2,
SlideRight = 3,
SlideUp = 4,
SlideDown = 5
}public class EventAutomationConfig
{
public List<EventSource> Sources { get; set; }
public List<ConditionGroup> ConditionGroups { get; set; }
public ConditionLogic GroupLogic { get; set; } // AND/OR between groups
public List<EventAction> Actions { get; set; }
}
public class EventSource
{
public string Alias { get; set; } // e.g., "site1"
public EventSourceType SourceType { get; set; }
public WebEventConfig? WebConfig { get; set; }
public FileSystemEventConfig? FileSystemConfig { get; set; }
public TimeEventConfig? TimeConfig { get; set; }
public OSEventConfig? OsConfig { get; set; }
public NetworkEventConfig? NetworkConfig { get; set; }
public AudioEventConfig? AudioConfig { get; set; }
}
public enum EventSourceType { Web, FileSystem, Time, OS, Network, Audio }
public enum ConditionLogic { And, Or }
public enum ConditionOperator { Contains, Equals, NotEquals, GreaterThan, LessThan, Changed, Matches, StartsWith, EndsWith, Exists, NotExists }
public enum EventActionType { Toast, Email, TextToSpeech, Popup, Webhook, AudioAlarm }Service that evaluates Event Automation configs. Fetches data from all sources, evaluates condition groups, and executes matched actions.
| Method | Description |
|---|---|
EvaluateAndExecuteAsync(Link link) |
Full evaluation: fetch → check conditions → run actions |
TestConfigAsync(EventAutomationConfig config) |
Test without executing actions; returns data + condition details |
TestSourceAsync(EventSource source) |
Test a single source; returns fetched key-value data |
| Value | Meaning |
|---|---|
| 0 | None |
| 1 | Hourly |
| 2 | Daily |
| 3 | Weekly |
| 4 | Monthly |
| 5 | Yearly |
| Value | Meaning |
|---|---|
| 0 | Balloon (system tray) |
| 1 | Toast (Windows notification) |
| 2 | Custom handler |
| 3 | Text-to-Speech |
Primary ViewModel managing the link tree, search, and all main window operations.
Key Properties:
RootLinks—ObservableCollection<LinkTreeItemViewModel>— hierarchical link treeSelectedLink— Currently selectedLinkTreeItemViewModelSearchText— Search filter text (triggers real-time filtering)IsLoading— Loading state indicatorFilteredLinks— Flattened search results
Key Commands:
AddLinkCommand— Opens add dialogEditLinkCommand— Opens edit dialog for selected linkDeleteLinkCommand— Deletes selected link with confirmationRefreshCommand— Reloads entire link treeOpenSettingsCommand— Opens settings windowImportCommand/ExportCommand— Import/export operationsSearchCommand— Executes search
DI Dependencies: ILinkService, ITagService, INotificationService, ILinkOpenerService, IImportExportService, IHotNavService, IAppService, IModalService, IStorageConfiguration
Add/Edit dialog ViewModel with per-type field visibility.
Key Properties:
Name,Url,Description,Notes,Command,TerminalTypeSelectedLinkType— CurrentLinkTypeAvailableTags/SelectedTags— Tag selectionIsHotclick,IsWinStartEnabled,TrayMenuPlacement,MenuPlacement,FolderOpenTargets- Time fields:
StartAt,RecurrenceKind,NotifyBeforeMinutes - ToDo fields:
Status - Slideshow fields:
SlideshowConfigJson - Event Automation fields:
EventAutomationConfigJson - Favorites:
IsFavorite
Commands: SaveCommand, CancelCommand, BrowseFileCommand, BrowseFolderCommand, DeleteCommand
Wraps a Link entity for tree display with expand/collapse and child lazy-loading.
Manages the notification panel display and actions.
Tag CRUD dialog with color picker.
Quick-access panel showing items with IsHotclick = true.
Rich-text editor for Notes-type links.
Time/Reminder management with recurrence and snooze.
Task list management with status tracking.
Individual slideshow panel with URL cycling and transitions.
Embedded browser window management.
Cross-type search with filtering and navigation.
Provides display names, icons, and descriptions for each LinkType value.