Built entirely with ServiceNow Build Agent for the #BuildWithBuildAgent Challenge
A full-featured equipment lending management system built on the ServiceNow platform, featuring role-based access control, automated loan workflows, email notifications, overdue detection, and custom React-based UI Pages β all generated through conversational AI in a single session.
- Overview
- Architecture
- Data Model
- Roles & Security
- Workflow & Automation
- UI Actions
- UI Pages
- Email Notifications
- File Structure
- What Build Agent Created
The Tool Lending Library is a ServiceNow scoped application that manages an equipment lending operation β think of it like a library, but for tools and machinery. It supports two user personas:
| Persona | Role | Capabilities |
|---|---|---|
| Librarian / Staff | x_828868_tool_le_0.librarian |
Full access: add/edit equipment, approve/deny borrow requests, check items in/out, mark items for maintenance, manage members, view all loans |
| Member | x_828868_tool_le_0.member |
Limited access: browse equipment catalog, view own loans, submit borrow requests (pending staff approval) |
graph TD
subgraph "π€ Roles"
R1["π Librarian<br/><i>Full Access</i>"]
R2["π Member<br/><i>Limited Access</i>"]
R1 -->|contains| R2
end
subgraph "ποΈ Data Model"
T1["π¦ Equipment<br/><i>name, category, serial#,<br/>condition, status, photo</i>"]
T2["π₯ Members<br/><i>name, email, phone,<br/>membership status, user link</i>"]
T3["π Loan Record<br/><i>equipment, member, dates,<br/>status, approved_by</i>"]
T3 -->|"equipment ref"| T1
T3 -->|"member ref"| T2
T2 -->|"user ref"| SU["π§ sys_user"]
end
subgraph "βοΈ Automation"
BR1["π Enforce Pending Status<br/><i>Before Insert</i>"]
BR2["π Prevent Member Modification<br/><i>Before Update</i>"]
SS["β° Flag Overdue Loans<br/><i>Daily @ 1:00 AM</i>"]
EN1["π§ Request Submitted"]
EN2["π§ Loan Approved"]
EN3["π§ Overdue Notice"]
end
subgraph "π±οΈ UI Actions"
UA1["β
Approve Request"]
UA2["β Deny Request"]
UA3["π₯ Mark as Returned"]
UA4["π§ Send to Maintenance"]
UA5["π€ Request to Borrow"]
end
subgraph "π₯οΈ UI Pages"
P1["π Staff Dashboard<br/><i>Pending Β· Active Β· Overdue</i>"]
P2["π Member Catalog<br/><i>Browse & Request Equipment</i>"]
end
| Field | Type | Required | Description |
|---|---|---|---|
name |
String (100) | β | Name of the equipment item |
category |
Choice | β | Hand Tool Β· Power Tool Β· Machinery Β· Other |
serial_number |
String (100) | β | Serial or asset tracking number |
condition |
Choice | β | Good Β· Fair Β· Needs Repair (default: Good) |
status |
Choice | β | Available Β· Checked Out Β· In Maintenance (default: Available) |
photo |
String (200) | β | Photo attachment reference |
| Field | Type | Required | Description |
|---|---|---|---|
name |
String (100) | β | Full name of the member |
contact_email |
β | Contact email address | |
contact_phone |
String (20) | β | Contact phone number |
membership_status |
Choice | β | Active Β· Inactive (default: Active) |
user |
Reference β sys_user |
β | Link to ServiceNow user account |
user_role |
Choice | β | Member Β· Librarian (default: Member) |
| Field | Type | Required | Description |
|---|---|---|---|
equipment |
Reference β Equipment | β | The equipment item being borrowed |
member |
Reference β Members | β | The member borrowing the item |
checkout_date |
DateTime | β | Set when loan is approved |
due_date |
DateTime | β | Expected return date |
return_date |
DateTime | β | Actual return date (null until returned) |
status |
Choice | β | Pending Approval Β· Active Β· Returned Β· Overdue |
approved_by |
Reference β sys_user |
β | Librarian who approved the request |
Librarian (x_828868_tool_le_0.librarian)
βββ contains β Member (x_828868_tool_le_0.member)
Equipment Table
| Operation | Librarian | Member |
|---|---|---|
| Read | β All records | β All records |
| Create | β | β |
| Write | β | β |
| Delete | β | β |
Members Table
| Operation | Librarian | Member |
|---|---|---|
| Read | β All records | |
| Create | β | β |
| Write | β | β |
| Delete | β | β |
Loan Record Table
| Operation | Librarian | Member |
|---|---|---|
| Read | β All records | |
| Create | β Any status | |
| Write | β All records | |
| Delete | β | β |
β οΈ Row-level security enforced via ACL scripts usingcurrent.member.user == gs.getUserID()
stateDiagram-v2
[*] --> PendingApproval: Member submits request
PendingApproval --> Active: Librarian approves
PendingApproval --> [*]: Librarian denies (record deleted)
Active --> Overdue: Daily scheduled job (due date passed)
Active --> Returned: Librarian marks returned
Overdue --> Returned: Librarian marks returned
Returned --> [*]
| Rule | Timing | Action | Purpose |
|---|---|---|---|
| Enforce Pending Status for Members | Before Insert | Forces pending_approval |
Prevents members from bypassing approval |
| Prevent Member Status Modification | Before Update | Aborts save with error | Blocks members from editing approved/active loans |
| Name | Frequency | Time | Purpose |
|---|---|---|---|
| Flag Overdue Loans | Daily | 1:00 AM | Queries active loans past due date β sets status to overdue |
| Button | Table | Visibility | Role | Action |
|---|---|---|---|---|
| β Approve Request | Loan Record | Status = Pending Approval | Librarian | Sets status β Active, records approved_by, sets checkout_date, updates equipment β Checked Out |
| β Deny Request | Loan Record | Status = Pending Approval | Librarian | Deletes the loan record, redirects to list |
| π₯ Mark as Returned | Loan Record | Status = Active or Overdue | Librarian | Sets status β Returned, records return_date, updates equipment β Available |
| π§ Send to Maintenance | Equipment | Status β In Maintenance | Librarian | Sets equipment status β In Maintenance |
| π€ Request to Borrow | Equipment | Status = Available | Member | Prompts for due date, creates loan record with Pending Approval status, looks up member by logged-in user |
A React-based dashboard for librarians featuring:
- Summary Cards β Real-time counts of Pending Approvals, Active Loans, and Overdue Items (fetched via Table API with
X-Total-Countheader) - Three Filtered Record Lists β Using
NowRecordListConnectedwith key prop filtering:- Pending Approvals (
status=pending_approval) - Active Loans (
status=active) - Overdue Items (
status=overdue)
- Pending Approvals (
- Design Token Theming β Uses
--now-*CSS variables for Horizon Design System compliance
Tech Stack: React 18.2.0 Β· @servicenow/react-components Β· ServiceNow Table API Β· Horizon Design Tokens
A React-based equipment browsing interface for members featuring:
- Welcome Header β Title and instructions for browsing equipment
- Equipment List β
NowRecordListConnectedshowing name, category, condition, and status columns - Row Navigation β Clicking equipment opens the standard form where the "Request to Borrow" button is available
- Clean Design β Styled with Horizon Design System tokens for platform consistency
| Notification | Trigger | Recipient | Subject |
|---|---|---|---|
| Borrow Request Submitted | Loan Record inserted with pending_approval |
Member (via member.user) |
"Borrow Request Submitted - {equipment}" |
| Loan Approved | Loan Record updated to active |
Member (via member.user) |
"Loan Approved - {equipment}" |
| Loan Overdue Notice | Loan Record updated to overdue |
Member (via member.user) |
"OVERDUE: {equipment} - Please Return Immediately" |
x_828868_tool_le_0/
βββ src/
β βββ client/ # React UI Pages
β β βββ staff-dashboard/
β β β βββ index.html # HTML entry with Polaris + Array.from polyfill
β β β βββ main.tsx # React bootstrap
β β β βββ app.tsx # Dashboard component (summary cards + filtered lists)
β β β βββ styles.css # Horizon design token styling
β β βββ member-catalog/
β β β βββ index.html # HTML entry
β β β βββ main.tsx # React bootstrap
β β β βββ app.tsx # Catalog browsing component
β β β βββ styles.css # Horizon design token styling
β β βββ utils/
β β β βββ fields.ts # display() and value() field helpers
β β βββ tsconfig.json # TypeScript configuration
β βββ fluent/ # ServiceNow Fluent DSL definitions
β βββ roles.now.ts # Librarian + Member roles
β βββ tables.now.ts # Equipment, Members, Loan Record tables
β βββ acls.now.ts # 12 ACL rules (read/create/write/delete Γ 3 tables)
β βββ business-rules.now.ts # Enforce pending status + prevent modification
β βββ ui-actions.now.ts # 5 UI Actions (approve, deny, return, maintenance, borrow)
β βββ notifications.now.ts # 3 email notifications
β βββ scheduled-script.now.ts # Daily overdue detection job
β βββ flag-overdue-loans.js # IIFE script for overdue flagging
β βββ nav.now.ts # Application menu + 6 navigator modules
β βββ ui-pages/
β βββ staff-dashboard.now.ts # Staff Dashboard UiPage definition
β βββ member-catalog.now.ts # Member Catalog UiPage definition
βββ package.json
βββ now.config.json
βββ tsconfig.json
In a single conversational session, Build Agent generated:
| Category | Count | Details |
|---|---|---|
| Roles | 2 | Librarian (with role inheritance), Member |
| Tables | 3 | Equipment, Members, Loan Record (with references) |
| Columns | 19 | String, Choice, Email, Reference, DateTime types |
| ACLs | 12 | Read/Create/Write/Delete for all 3 tables with script-based row-level security |
| Business Rules | 2 | Insert enforcement + update protection |
| UI Actions | 5 | Approve, Deny, Return, Maintenance, Borrow (with client+server patterns) |
| Email Notifications | 3 | Request submitted, approved, overdue |
| Scheduled Scripts | 1 | Daily overdue detection |
| UI Pages | 2 | React-based Staff Dashboard + Member Catalog |
| Navigation | 7 | 1 Application Menu + 6 modules (3 lists, 1 separator, 2 direct links) |
| Total Metadata Records | 64 | Installed in one deployment |
- β Zero build errors on final compilation
- β Zero UI diagnostics errors β both pages load cleanly
- β All API calls return 200 β Table API and GraphQL queries verified
- β Horizon Design System compliant β CSS design tokens validated
This application was built entirely through natural language conversation with ServiceNow's Build Agent β no manual coding, no form-based configuration, no copy-pasting. From initial requirements to a fully deployed, production-ready application with role-based security, automated workflows, email notifications, and custom React UIs.
The future of ServiceNow development is conversational.