The Work
Make the operating rules explicit
I separated technician, manager, and administrator responsibilities so each role had the controls it needed. Technicians need to submit and review their requests. Managers need to see the queue, check availability, and approve or reject. Administrators need to manage users, settings, and technician records. Those differences appear in the Home views and in permission checks around the actions.
Availability is calculated across six shift types. The default configuration assigns 120 weekly hours overall and a preferred allocation of 20 per shift. When a shift runs out, the borrowing workflow checks other shifts rather than ignoring the limit. Administrators can adjust those allocations to fit the operation.
Bulk approval made that calculation more involved. Requests needing borrowed hours are presented in submission order. As a manager selects a lending shift for each request, the interface subtracts the hours already assigned in that same batch. That keeps the next selection from showing capacity already committed by an earlier selection.
| Role or step | Action | Rule that keeps the workflow coherent |
|---|---|---|
| Technician | Submit a request or edit their own pending request | Validate date, hours, notes, and duplicate requests |
| Manager | Approve, reject, or arrange borrowed hours | Check available capacity before committing the decision |
| Bulk borrowing | Allocate lending-shift hours in submission order | Subtract allocations already selected in the same batch |
| Administrator | Manage users, technicians, and configuration | Keep account and linked technician participation aligned |
Keep the record connected to the decision
The request model includes the technician, date, hours, status, notes, and borrowing information. A technician submits through a modal; managers and administrators receive a direct message with decision buttons. The stored request moves through pending, approved, or rejected states, so the conversation is tied to a record. Validation rejects duplicate requests for the same technician and date and checks hours, dates, and required notes.
I treated the list a manager sees as part of the workflow too. Edit and borrowing dialogs retain the parent list’s view identifier, allowing the list to refresh after a decision. Refreshed checkbox controls clear earlier selections instead of carrying them into the next action. Bulk changes are saved before status notifications are sent, keeping the message aligned with the stored decision.
User registration and technician records also need to stay aligned. Deactivating an account without updating its linked technician would leave the two parts of the workflow disagreeing about who can participate. The administrative lifecycle updates those linked records, while technicians are limited to editing their own pending requests.
Build for deployment and support
The application uses Python and Slack Bolt, with AWS Lambda handling the deployed workflow and DynamoDB retaining the data. API Gateway provides the HTTP entry path. A storage adapter separates persistence from application behavior, with local development options. Bulk actions batch record changes and explicitly flush them, avoiding a separate storage round trip for every selected request.
Slack’s short interaction window shaped the deployment. Manager notification broadcasts run through a separate asynchronous Lambda invocation, rather than making a technician wait while the application messages every reviewer. Warm-start application reuse, scheduled warmup, and CloudWatch monitoring address cold-start behavior and make failures easier to investigate. The handler checks Slack retry headers to reduce repeated processing.
Work through the less obvious paths
Testing covered the request lifecycle, roles, quota handling, and management actions. I also coordinated a change to how the application reads profiles, removing a broader Slack permission requirement and updating the initial administrator setup. That kept user identification working with more limited access to Slack data.
I managed requirements and development through versioned tasks, review notes, and handoffs. I coordinated changes across the interface, storage, and notifications, checked the workflow against its operating rules, and documented how administrators could configure and support it.
THE DELIVERABLES
What I delivered
- Slack submission, review, availability, and FIFO borrowing interfaces
- Linked user and technician lifecycle with role-aware request actions
- Persistent storage, batched updates, and asynchronous reviewer notifications
- AWS deployment configuration, operating guides, and recorded test reports
A CLOSER LOOK
Project exhibits
Approve requests that need borrowed hours
The borrowing dialog brings the allocation decision into approval. Requests exceeding the shift quota are presented in submission order, and the manager selects a lending shift before approving the batch. Available hours update as selections are made.

THE OUTCOME
Where the work stands
The application was deployed and validated for technician requests, manager approvals, and shift-capacity checks. It keeps those decisions and the request history in one operational workflow.
SCOPE AND LIMITATIONS
What the work establishes
The workflow has not been evaluated in a before-and-after time study.
Shift quotas must be configured for the operation. Retry checks reduce duplicate processing but do not guarantee that every request is processed exactly once.
