A Go application for managing on-call schedules. It provides a RESTful API with two main endpoints:
- Create schedules for teams with specific time windows and weekdays
- Query the current on-call members for a team at a given time
- Thread-safe in-memory storage for schedules
- Support for multiple schedules per team
- Flexible weekday and time range configuration
- Timezone-aware time comparisons
- Structured logging with Zap
- Graceful shutdown handling
- Configuration via YAML file or environment variables
The application can be configured using either a YAML file or environment variables.
Create a config.yaml file (default included in the repository):
server:
address: "0.0.0.0"
port: 1373Configuration can be overridden using environment variables with the ONCALL_ prefix:
export ONCALL_SERVER__ADDRESS=localhost
export ONCALL_SERVER__PORT=8080Note: Use double underscores (__) to represent nested configuration keys.
- Address:
0.0.0.0 - Port:
1373
Start the server:
./oncall-scheduleThe API will be available at http://localhost:1373 (or your configured address/port).
Create a new on-call schedule for a team.
Endpoint: POST /schedule
Request Body:
{
"name": "Weekend Coverage",
"team": "backend-team",
"members": ["Alice", "Bob", "Charlie"],
"days": ["Saturday", "Sunday"],
"start": "9:00AM",
"end": "5:00PM"
}Fields:
name(string, required): Schedule name/identifierteam(string, required): Team identifiermembers(array, required): List of team members in the rotation (must not be empty)days(array, required): Weekdays when this schedule applies (case-insensitive: "Monday", "Tuesday", etc.)start(string, required): Start time in 12-hour format (e.g., "9:00AM", "1:30PM")end(string, required): End time in 12-hour format (must be after start time)
Response:
201 Createdon success400 Bad Requestwith error details on validation failure
Example:
curl -X POST http://localhost:1373/schedule \
-H "Content-Type: application/json" \
-d '{
"name": "Weekday Shift",
"team": "ops-team",
"members": ["John", "Jane", "Joe"],
"days": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"start": "9:00AM",
"end": "5:00PM"
}'Retrieve the on-call members for a team at a specific time.
Endpoint: GET /schedule
Query Parameters:
team(string, required): Team identifiertime(string, required): RFC3339 formatted timestamp (e.g., "2025-04-26T09:00:00Z")
Response:
200 OKwith array of member names:["Member1", "Member2"]404 Not Foundif no schedule matches the query (wrong team, day, or time outside schedule window)400 Bad Requestif parameters are missing or invalid
Example:
curl "http://localhost:1373/schedule?team=ops-team&time=2025-04-28T14:30:00Z"Response:
["John", "Jane", "Joe"]- Validates all required fields are present and non-empty
- Parses weekday strings (case-insensitive)
- Parses start/end times in 12-hour format
- Validates start time is before end time
- Stores schedule in thread-safe in-memory storage
- Multiple schedules can exist per team
- Checks if the team exists
- Iterates through the team's schedules
- Matches the weekday of the requested time
- Constructs timezone-aware start/end times for comparison
- Returns members if the requested time falls within the schedule window
- Uses the timezone from the requested time for accurate comparisons