Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6c4812f
feat(api,ui): Add cursor-based pagination and workflow updates
bugrakosen May 20, 2026
9cde02d
feat(config): add support for configurable base path
bugrakosen May 20, 2026
fe774bd
refactor(dispatcher): decouple zombie cleanup logic
bugrakosen May 20, 2026
d454170
chore: Upgrade versions.
bugrakosen May 21, 2026
8a2164b
tests: test fix.
bugrakosen May 21, 2026
91f0d4b
feat: Add runtime base path config via /config.js endpoint
bugrakosen May 21, 2026
de110c5
fix: Change log level to information.
bugrakosen May 21, 2026
f548285
fix: Refactor config usage and log API base path at startup.
bugrakosen May 21, 2026
5314a5c
feat: Add RabbitMQ Management API support for queue monitoring
bugrakosen May 22, 2026
fe5b64c
fix: Update SDK package versions and refine sync logging
bugrakosen Jun 7, 2026
c212b80
feat: Block unnecessary user activity logs when workflow engine trigg…
bugrakosen Jun 16, 2026
a054d90
feat: Change main ui color.
bugrakosen Jul 9, 2026
1263a5b
feat: Add local job testing support and update dependencies
bugrakosen Jul 9, 2026
ae85b6c
fix: Update dependencies and test imports
bugrakosen Jul 9, 2026
6b9564d
feat: Refactor alert timeout handling and improve test reliability
bugrakosen Jul 10, 2026
8097d10
feat: Add infinite scroll to JobList card view
bugrakosen Jul 15, 2026
3ec6352
feat: Add API key management, MCP server, and UI integration
bugrakosen Jul 18, 2026
5e81213
docs: Update docs.
bugrakosen Jul 18, 2026
e7d7853
feat: Enforce MCP tool conventions, filtering, and prompts
bugrakosen Jul 18, 2026
7929570
feat: Expand MCP tools for Milvaion AI; update docs
bugrakosen Jul 18, 2026
982c0b3
feat: Add MediatR queries for MCP tool API analysis & reports
bugrakosen Jul 19, 2026
a58b859
feat: UI enhancements, add new mcp tools, impove workflow condition n…
bugrakosen Jul 19, 2026
90b9395
feat: UI enhancements.
bugrakosen Jul 20, 2026
d2c42ef
feat: UI/UX overhaul: dashboards, JSON, triggers, resource API
bugrakosen Jul 20, 2026
49e3a57
feat: Update job deletion logic to prevent removal if jobs are runnin…
bugrakosen Jul 20, 2026
23ff3aa
fix: Css fix.
bugrakosen Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -362,3 +362,7 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
/CoverageReport

# Local environment variables
.env
.env.local
9 changes: 8 additions & 1 deletion Milvaion.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<File Path="docs/portaldocs/20-workflows.md" />
<File Path="docs/portaldocs/21-reporter-worker.md" />
<File Path="docs/portaldocs/22-reports.md" />
<File Path="docs/portaldocs/23-local-job-testing.md" />
</Folder>
<Folder Name="/src/">
<Project Path="src/MilvaionUI/" Type="Website" DisplayName="MilvaionUI">
Expand Down Expand Up @@ -165,7 +166,13 @@
<BuildType Solution="TemplateTest|*" Project="Debug" />
</Project>
</Folder>
<Folder Name="/tests/" />
<Folder Name="/tests/">
<Project Path="tests/SampleWorker.Tests/SampleWorker.Tests.csproj">
<BuildType Solution="TemplateTest|*" Project="Debug" />
<Build Solution="Debug|*" Project="false" />
<Build Solution="TemplateTest|*" Project="false" />
</Project>
</Folder>
<Folder Name="/tests/IntegrationTests/">
<Project Path="tests/Milvaion.IntegrationTests/Milvaion.IntegrationTests.csproj">
<BuildType Solution="TemplateTest|*" Project="Release" />
Expand Down
85 changes: 70 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

<p align="center">
A distributed job scheduling system built on .NET 10
<br>
<sub>Already on <b>Hangfire</b> or <b>Quartz.NET</b>? Keep it — <a href="#already-running-hangfire-or-quartznet">add Milvaion monitoring in two lines</a>.</sub>
</p>

<div align="center">
Expand Down Expand Up @@ -60,6 +62,53 @@ Milvaion solves these problems by **completely separating scheduling from execut

---

## Already Running Hangfire or Quartz.NET?

**You don't have to migrate to adopt Milvaion.**

Milvaion plugs into the scheduler you already run. Your scheduler keeps owning triggers, storage and cron expressions. Your job code doesn't change. Milvaion adds one real-time dashboard across every service, plus persisted execution history, metrics and alerting.

```csharp
// Hangfire - your existing setup stays exactly as it is
builder.Services.AddMilvaionHangfireIntegration(builder.Configuration);
builder.Services.AddHangfire((sp, config) => config.UseMilvaion(sp));

// Quartz.NET - your existing setup stays exactly as it is
builder.Services.AddMilvaionQuartzIntegration(builder.Configuration);
builder.Services.AddQuartz(q => q.UseMilvaion(builder.Services));
```

That's the whole integration.

### The problem this solves

A typical .NET estate ends up with background jobs scattered across a dozen services — each with its own dashboard behind its own URL and its own auth. Nobody can answer *"which jobs failed last night?"* without opening every one of them, and history vanishes when the retention window rolls over.

| Before | After |
|--------|-------|
| One dashboard per service | One dashboard for the whole estate |
| History limited by Hangfire/Quartz retention | Full execution history in PostgreSQL |
| Logs only in each app's own sink | Real-time log streaming per execution |
| Failures noticed when someone complains | Multi-channel alerts on failure and timeout |
| No cross-service metrics | Success rate, duration and EPM per job |

### The adoption path

1. **Add monitoring** — two lines per application. No migration window, no change to job code.
2. **Get visibility** — every Hangfire and Quartz.NET job appears in the dashboard, flagged as external.
3. **Migrate selectively, or never** — when one job outgrows in-process execution, move just that job to a Milvaion worker. Everything else keeps running untouched.

Plenty of teams stop at step 2. That's a perfectly good outcome.

| Scheduler | Package | Status |
|-----------|---------|--------|
| **Hangfire** | `Milvasoft.Milvaion.Sdk.Worker.Hangfire` | ✅ Available |
| **Quartz.NET** | `Milvasoft.Milvaion.Sdk.Worker.Quartz` | ✅ Available |

📖 **[Full Integration Guide →](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/external-schedulers)**

---

## Features

![Milvaion Real Time](https://portal.milvasoft.com/assets/images/executions-4b5918b7fca1b603f54be133c7880397.gif)
Expand Down Expand Up @@ -105,26 +154,28 @@ Milvaion solves these problems by **completely separating scheduling from execut
- **Maintenance Worker** - Milvaion self data warehouse cleanup and archival

### External Scheduler Integration
Already using **Quartz.NET** or **Hangfire**? Keep your existing scheduler and gain Milvaion's monitoring capabilities:

| Scheduler | Package | Status |
|-----------|---------|--------|
| **Quartz.NET** | `Milvasoft.Milvaion.Sdk.Worker.Quartz` | ✅ Available |
| **Hangfire** | `Milvasoft.Milvaion.Sdk.Worker.Hangfire` | ✅ Available |
Milvaion also monitors jobs running in **Quartz.NET** and **Hangfire** without replacing them — see [Already Running Hangfire or Quartz.NET?](#already-running-hangfire-or-quartznet) above.

```csharp
// Quartz.NET Integration
builder.Services.AddMilvaionQuartzIntegration(builder.Configuration);
builder.Services.AddQuartz(q => q.UseMilvaion(builder.Services));
### MCP Server
Point Claude Code, Cursor or GitHub Copilot at Milvaion and ask about your jobs in plain language:

// Hangfire Integration
builder.Services.AddMilvaionHangfireIntegration(builder.Configuration);
builder.Services.AddHangfire((sp, config) => config.UseMilvaion(sp));
```json
{
"mcpServers": {
"milvaion": {
"type": "http",
"url": "https://milvaion.yourcompany.com/mcp",
"headers": { "X-ApiKey": "your-api-key" }
}
}
}
```

External jobs appear in Milvaion dashboard with full monitoring, metrics, and execution history - without changing your existing scheduler setup.
> *"Which jobs failed last night and why?"*

More than forty tools — reading, triggering, pausing, editing and deleting — each gated by the same permissions used everywhere else. A read-only api key gives an assistant full visibility and no ability to change anything. Milvaion is the data source here; it never calls a language model and stores no model provider keys.

[For more information...](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/external-schedulers)
📖 **[MCP Server Guide →](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/mcp-server)**

---

Expand Down Expand Up @@ -378,6 +429,9 @@ Each workflow can also configure **Max Step Retries** and a **Timeout** (auto-ca
| Document | Description |
|----------|-------------|
| [Introduction](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/introduction) | What is Milvaion, when to use it |
| [Hangfire & Quartz.NET Integration](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/external-schedulers) | Keep your existing scheduler, add Milvaion monitoring |
| [Api Keys](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/api-keys) | Credentials for CI pipelines, scripts and MCP clients |
| [MCP Server](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/mcp-server) | Connect Claude Code, Cursor or Copilot to Milvaion |
| [Quick Start](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/quick-start) | Get running in under 10 minutes |
| [Core Concepts](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/core-concepts) | Architecture and key terms |
| [Your First Worker](https://portal.milvasoft.com/docs/1.0.1/open-source-libs/milvaion/your-first-worker) | Create a custom worker |
Expand All @@ -397,6 +451,7 @@ Each workflow can also configure **Max Step Retries** and a **Timeout** (auto-ca
| [Architecture](./docs/githubdocs/ARCHITECTURE.md) | Technical architecture deep-dive |
| [Development](./docs/githubdocs/DEVELOPMENT.md) | Development environment setup |
| [Worker SDK](./docs/githubdocs/WORKER-SDK.md) | Worker SDK reference |
| [MCP Server](./docs/githubdocs/MCP-SERVER.md) | MCP server and api key auth internals |
| [Security](./SECURITY.md) | Security policies |

---
Expand Down
14 changes: 13 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,19 @@
labels:
- "com.milvaion.service=grafana"
- "com.milvaion.description=Grafana metrics dashboard"

pgweb:
image: sosedoff/pgweb:latest
container_name: milvaion-pgweb
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: "postgres://postgres:N4SQp.qW%3E6%3FxwWzg@postgres:5432/MilvaionDb?sslmode=disable"
ports:
- "8082:8081"
networks:
- milvaion-network
restart: unless-stopped
volumes:
postgres_data:
driver: local
Expand Down
6 changes: 6 additions & 0 deletions docs/githubdocs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,13 @@ CREATE TABLE "ScheduledJobs" (
"JobType" VARCHAR(200) NOT NULL,
"JobData" JSONB,
"CronExpression" VARCHAR(100),
-- Configured start time, NOT the next run. The dispatcher advances a recurring
-- job's schedule in Redis and never writes it back here, so this goes stale
-- after the first run. Read the Redis sorted set for the live schedule.
"ExecuteAt" TIMESTAMPTZ,
-- Set when a one-time job is dispatched, so it is never scheduled again even if
-- Redis is flushed. Separate from IsActive: "finished" is not "switched off".
"CompletedAt" TIMESTAMPTZ,
"IsActive" BOOLEAN DEFAULT TRUE,
"ConcurrentExecutionPolicy" INTEGER DEFAULT 0,
"TimeoutMinutes" INTEGER,
Expand Down
Loading