Skip to content

Commit 77b0303

Browse files
authored
Merge branch 'main' into alert-autofix-1
2 parents 1e49ad9 + 76bb2dc commit 77b0303

24 files changed

Lines changed: 432 additions & 113 deletions

.github/dependabot.yml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@
55

66
version: 2
77
updates:
8-
# Enable version updates for Docker
8+
- package-ecosystem: "nuget"
9+
directory: "/src/RandomAPI"
10+
schedule:
11+
interval: "weekly"
12+
913
- package-ecosystem: "docker"
10-
# Look for a `Dockerfile` in the src/randomdapi directory
11-
directory: "src/RandomAPI/"
12-
# Check for updates once a week
14+
directory: "/src/RandomAPI"
1315
schedule:
1416
interval: "weekly"
1517

16-
# Enable version updates for GitHub Actions
1718
- package-ecosystem: "github-actions"
18-
# Workflow files stored in the default location of `.github/workflows`
19-
# You don't need to specify `/.github/workflows` for `directory`. You can use
19+
directory: "/"
20+
schedule:
21+
interval: "weekly"

.github/workflows/CodeQL_PR_Analysis.yml

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,51 @@ permissions:
55

66
on:
77
pull_request:
8+
# Triggers analysis on pull requests targeting the main branch
89
branches: [ main ]
9-
10+
push:
11+
# Also good practice to run on pushes to main for full analysis
12+
branches: [ main ]
13+
1014
jobs:
1115
analyze:
1216
name: Analyze code with CodeQL
17+
# Use newer, stable runner
1318
runs-on: ubuntu-latest
19+
20+
# Permission setup is highly recommended for security analysis
21+
permissions:
22+
security-events: write
23+
actions: read
24+
contents: read
1425

1526
steps:
1627
- name: Checkout repository
17-
uses: actions/checkout@v3
28+
# Use the latest stable version
29+
uses: actions/checkout@v4
30+
with:
31+
# Important for CodeQL to fetch history
32+
fetch-depth: 0
33+
34+
# NEW: Setup the .NET SDK environment
35+
- name: Setup .NET
36+
uses: actions/setup-dotnet@v4
37+
with:
38+
# Assuming you are targeting .NET 8, adjust if needed
39+
dotnet-version: '8.0.x'
1840

1941
- name: Initialize CodeQL
2042
uses: github/codeql-action/init@v3
2143
with:
2244
languages: csharp
2345
# Using default queries (security + quality)
24-
# You can also specify custom queries if needed
2546

26-
- name: Autobuild
27-
uses: github/codeql-action/autobuild@v3
47+
# FIX: Removed 'github/codeql-action/autobuild'.
48+
# C# projects must be built explicitly so CodeQL can monitor the compiler output.
49+
- name: Build Project
50+
# Run dotnet build on your project directory to compile the code
51+
# Based on your Dependabot config, the project is in 'src/RandomAPI'
52+
run: dotnet build src/RandomAPI/RandomAPI.csproj
2853

2954
- name: Perform CodeQL Analysis
3055
uses: github/codeql-action/analyze@v3
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
using RandomAPI.Controllers;
21
using RandomAPI.DTOs;
32

43
public interface IHoursService
54
{
65
HoursResponseDto Calculate(HoursRequestDto request);
76
}
8-
9-
10-

src/RandomAPI/APIServices/Services/IWebhookService.cs renamed to src/RandomAPI/APIServices/ServiceInterfaces/IWebhookService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ public interface IWebhookService
33
/// <summary>
44
/// Sends a webhook notification to all registered listeners.
55
/// </summary>
6-
Task BroadcastAsync<T>(T payload);
6+
Task BroadcastAsync<T>(T payload) where T : class;
77

88
/// <summary>
99
/// Registers a new webhook listener URL.

src/RandomAPI/APIServices/Services/DatabaseService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Dapper;
22
using Microsoft.Data.Sqlite;
3+
34
public class DatabaseService
45
{
56
private readonly string _connectionString;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace RandomAPI.Services.Webhooks
2+
{
3+
public interface ICustomWebhookPayload : IWebHookPayload
4+
{
5+
DateTime Timestamp { get; set; }
6+
}
7+
8+
public interface IWebHookPayload
9+
{
10+
string content { get; set; }
11+
}
12+
}

src/RandomAPI/APIServices/Services/HoursService.cs renamed to src/RandomAPI/APIServices/Services/TimeOutService.cs

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
1-
using Microsoft.Extensions.Logging;
2-
using RandomAPI.DTOs;
31
using System.Globalization;
42
using System.Text.RegularExpressions;
3+
using Microsoft.Extensions.Logging;
4+
using RandomAPI.DTOs;
55

6-
public class HoursService : IHoursService
6+
public class TimeOutService(ILogger<IHoursService> logger) : IHoursService
77
{
8-
private readonly ILogger<IHoursService> _logger;
9-
10-
public HoursService(ILogger<IHoursService> logger)
11-
{
12-
_logger = logger;
13-
}
14-
158
public HoursResponseDto Calculate(HoursRequestDto request)
169
{
1710
var rounded = request.Hours.Select(RoundToQuarter).ToList();
@@ -42,7 +35,7 @@ public HoursResponseDto Calculate(HoursRequestDto request)
4235
HoursWorkedRounded = hoursWorkedRounded,
4336
RemainingHours = remaining,
4437
MinTimeOut = min.ToString("hh:mm tt"),
45-
MaxTimeOut = max.ToString("hh:mm tt")
38+
MaxTimeOut = max.ToString("hh:mm tt"),
4639
};
4740
}
4841

@@ -57,23 +50,23 @@ private DateTime ParseTimeInput(string input)
5750
if (Regex.IsMatch(input, @"^\d{1,2}(am|pm)$"))
5851
input = input.Replace("am", ":00am").Replace("pm", ":00pm");
5952

60-
string[] formats =
61-
{
62-
"h:mmtt", "hh:mmtt",
63-
"htt", "hhtt",
64-
"h tt", "hh tt"
65-
};
66-
67-
if (DateTime.TryParseExact(input, formats,
68-
CultureInfo.InvariantCulture,
69-
DateTimeStyles.None,
70-
out DateTime parsed))
53+
string[] formats = { "h:mmtt", "hh:mmtt", "htt", "hhtt", "h tt", "hh tt" };
54+
55+
if (
56+
DateTime.TryParseExact(
57+
input,
58+
formats,
59+
CultureInfo.InvariantCulture,
60+
DateTimeStyles.None,
61+
out DateTime parsed
62+
)
63+
)
7164
{
7265
return parsed;
7366
}
7467
//if fail, throw and log
7568
Exception e = new FormatException("Invalid time format.");
76-
_logger.LogWarning(e, "Invalid time format.");
69+
logger.LogWarning(e, "Invalid time format.");
7770
throw e;
7871
}
7972

@@ -82,6 +75,3 @@ private double RoundToQuarter(double hours)
8275
return Math.Round(hours * 4) / 4.0;
8376
}
8477
}
85-
86-
87-
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace RandomAPI.Services.Webhooks
2+
{
3+
public class WebhookPayload : ICustomWebhookPayload
4+
{
5+
public string content { get; set; } = "";
6+
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
7+
}
8+
9+
public class DiscordWebhookPayload : IWebHookPayload
10+
{
11+
public string content { get; set; } = "";
12+
}
13+
}
Lines changed: 28 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,41 @@
11
using System.Collections.Concurrent;
22

3-
public class WebhookService : IWebhookService
3+
namespace RandomAPI.Services.Webhooks
44
{
5-
private readonly ConcurrentDictionary<string, byte> _webhookUrls = new();
6-
private readonly HttpClient _client = new();
7-
private readonly ILogger<IWebhookService> _logger;
8-
9-
public WebhookService(ILogger<IWebhookService> logger)
5+
public class WebhookService : IWebhookService
106
{
11-
_logger = logger;
12-
}
13-
14-
public IEnumerable<string> GetListeners() => _webhookUrls.Keys;
7+
private readonly ConcurrentDictionary<string, byte> _webhookUrls = new();
8+
private readonly HttpClient _client = new();
9+
private readonly ILogger<IWebhookService> _logger;
1510

16-
public bool AddListener(string url)
17-
=> _webhookUrls.TryAdd(url, 0);
11+
public WebhookService(ILogger<IWebhookService> logger)
12+
{
13+
_logger = logger;
14+
}
1815

19-
public bool RemoveListener(string url)
20-
=> _webhookUrls.TryRemove(url, out _);
16+
public IEnumerable<string> GetListeners() => _webhookUrls.Keys;
2117

22-
public async Task BroadcastAsync<T>(T payload)
23-
{
24-
// Snapshot-safe enumeration
25-
var tasks = _webhookUrls.Keys.Select(async url =>
18+
public bool AddListener(string url) => _webhookUrls.TryAdd(url, 0);
19+
20+
public bool RemoveListener(string url) => _webhookUrls.TryRemove(url, out _);
21+
22+
public async Task BroadcastAsync<T>(T payload) where T : class
2623
{
27-
try
28-
{
29-
await _client.PostAsJsonAsync(url, payload);
30-
}
31-
catch (Exception ex)
24+
// Snapshot-safe enumeration
25+
var tasks = _webhookUrls.Keys.Select(async url =>
3226
{
27+
try
3328
{
34-
_logger.LogWarning(ex, "WebhookPayload failed to Post");
29+
await _client.PostAsJsonAsync(url, payload);
3530
}
36-
}
37-
});
38-
await Task.WhenAll(tasks);
31+
catch (Exception ex)
32+
{
33+
{
34+
_logger.LogWarning(ex, "WebhookPayload failed to Post");
35+
}
36+
}
37+
});
38+
await Task.WhenAll(tasks);
39+
}
3940
}
4041
}
41-
42-
public interface IWebhookPayload
43-
{
44-
DateTime Timestamp { get; set; }
45-
string Message { get; set; }
46-
47-
}
48-
49-
public class WebhookPayload : IWebhookPayload
50-
{
51-
public string Message { get; set; } = "";
52-
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
53-
}

src/RandomAPI/Controllers/TimeOutController.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,3 @@ public ActionResult<HoursResponseDto> Calculate(HoursRequestDto dto)
3131
}
3232
}
3333
}
34-

0 commit comments

Comments
 (0)