<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Building BuildGuard: Bringing Graphs and AI to Construction Payment Reviews]]></title><description><![CDATA[How I connected agreements, previous payments, approvals and inspection evidence with Python, FalkorDB and Gemini.]]></description><link>https://okeydee.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 05 Nov 2026 03:28:14 GMT</lastBuildDate><atom:link href="https://okeydee.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building BuildGuard: Bringing Graphs and AI to Construction Payment Reviews]]></title><description><![CDATA[How I connected agreements, previous payments, approvals and inspection evidence with Python, FalkorDB and Gemini.]]></description><link>https://okeydee.hashnode.dev/building-buildguard-bringing-graphs-and-ai-to-construction-payment-reviews</link><guid isPermaLink="true">https://okeydee.hashnode.dev/building-buildguard-bringing-graphs-and-ai-to-construction-payment-reviews</guid><dc:creator><![CDATA[okechukwudiyoke]]></dc:creator><pubDate>Mon, 19 Oct 2026 05:53:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ad5a39a39ceb5d5d5556bc7/fa6a64e3-d5c9-4d99-a7f2-f3a40b53f667.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A contractor's payment request can look straightforward: a description of work and an amount to pay. Reviewing it properly means following a trail. What was agreed? What has already been paid? Was additional work authorised? Has someone inspected the work and confirmed that it meets the specification? My background is in construction, real estate and business operations in Nigeria. These are the kinds of questions I bring to a payment review. As I learn to build software and automation tools, I wanted to work on a problem I could understand from both the operational and technical sides. That became BuildGuard, a construction payment review prototype that I built and submitted to Graph Hacks, organised by WeMakeDevs and powered by FalkorDB. Its starting point is simple: review before release. Connect the relevant records, run defined checks and give the reviewer an explanation supported by the evidence. I kept the first version focused on a fixed-price demo policy where payment requires verified completion. BuildGuard examines a request against its agreement, previous payments, included variations, required approvals and inspection records. It produces one of three recommendations: APPROVE, HOLD or INVESTIGATE. Each recommendation supports a human review. The stack is Python for the review logic, Flask for the local API and dashboard, FalkorDB for the connected records and saved reviews, and Gemini for the tool-calling assistant. Docker runs the database locally. The graph model grew directly from the questions I needed to answer: Record Role in the review Project Groups the construction agreements Agreement Records the scope, value and payment rule PaymentRequest Identifies the amount being requested against an agreement Payment Records an earlier payment against that agreement Variation Represents additional work linked to the agreement Person Represents a required approver or the person recording an inspection Inspection Records completion and specification checks, with an evidence reference Review Preserves the findings and figures returned by a saved review</p>
<p>Those relationships let the application follow a request to its agreement, find previous payments, inspect included variations and check the required approvals. The review depends on what those connections show. For example, this query identifies required approvers whose approval has not been recorded for an included variation: MATCH (r:PaymentRequest {id: $payment_id})-[:INCLUDES_VARIATION]-&gt;(v:Variation) MATCH (v)-[:REQUIRES_APPROVAL_FROM]-&gt;(person:Person) OPTIONAL MATCH (person)-[approval:APPROVED]-&gt;(v) WITH r, v, person, approval WHERE approval IS NULL RETURN r.id, v.id, person.id, person.name The result tells the reviewer which variation needs attention and whose approval is missing. Other queries retrieve previous payments, approved variations and inspection evidence. FalkorDB supplies the connected context that the review needs on each run. The main demo agreement is worth ₦5 million, with an approved drainage variation of ₦500,000. That gives an authorised value of ₦5.5 million. After ₦2 million in previous payments, the remaining balance is ₦3.5 million. A request for another ₦5 million therefore exceeds the remaining balance by ₦1.5 million. BuildGuard returns INVESTIGATE and includes that calculation in its findings. I used three independent scenarios to check the different outcomes: Request Demo evidence Recommendation PAY-001 ₦5 million requested against a remaining balance of ₦3.5 million INVESTIGATE PAY-002 ₦3.5 million requested, with the configured demo evidence checks passing APPROVE PAY-003 Required agreement inspection evidence is missing HOLD</p>
<p>All of these figures and evidence references are synthetic demo data. APPROVE means that the implemented checks passed for human review. The scenarios are independent, and the application does not reserve or release funds. An approved variation also affects the arithmetic. Under the demo policy, the variation needs approval from both named approvers before its value contributes to the authorised amount. Recording that approval can change both the missing-approval findings and the remaining balance. This was a useful way to see how one relationship can affect several parts of a review. The AI assistant sits on top of that review process. When someone asks BuildGuard to explain a selected request, Gemini has two tools available:</p>
<ul>
<li><p>get_payment_review retrieves the current review from the graph and Python policy engine.</p>
</li>
<li><p>get_review_history retrieves up to three recent saved reviews for that request. The agent loop requires both sources before accepting a completed answer. The dashboard also exposes the retrieved tool results, so the user can inspect what the assistant received. Python produces the structured recommendation. Gemini is instructed to explain that recommendation, the figures, the findings and relevant changes in the retrieved history. Its available tools retrieve evidence; they cannot change approvals, inspections or payments. Any explanation still needs to be checked against those tool results. The interface brings those pieces together. A reviewer can select a request, refresh its current preview, save a review, inspect supporting references and ask a question about the findings. Previewing reads the current evidence. Saving creates a review record linked to the request. Saved reviews were particularly useful as the project developed. Each preserves the report's figures and findings with a timestamp and identifier. That gives a reviewer a way to compare an earlier report with a fresh one after the evidence changes. The dashboard shows up to 20 saved reviews per request, while the agent receives up to three. That distinction matters. The assistant can discuss the history it retrieved, but it should not claim to have examined every past review. Similarly, a field missing from an older report does not prove that the underlying database lacked that evidence at the time. Building this helped me make operational assumptions explicit. “The work is complete” becomes a recorded inspection linked to the relevant agreement or variation. “The variation was approved” becomes a relationship to the required approver. “The balance looks right” becomes a calculation supported by the agreement, approved variations and previous payments. I also worked through Python syntax and indentation errors, Cypher query mistakes and the practical steps of connecting a local database, API and browser interface. Running the scenarios and checking their findings gave me concrete feedback as I learned. I used ChatGPT/Codex for assistance with coding, debugging, documentation and test design. I supplied the construction use case, made the product and policy decisions, and ran and checked the demo scenarios through guided development sessions. Understanding why a recommendation changed was an important part of that work. The current version has clear boundaries. It runs locally and uses a narrow demo payment policy. Ledger and inspection references are fixture values, rather than independently verified documents or bank records. Saved reports are snapshots, rather than a tamper-proof audit system. Production use would need access controls, document verification, broader payment policies, exact monetary arithmetic and a consistent approach to concurrent reads and writes. The prototype also makes failures visible: a database failure produces HOLD with an incomplete review, while an AI provider failure produces an explicit agent error. The repository includes setup instructions, a Docker Compose configuration, a pinned database image and a demo seeder. The review dashboard and saved-history features work without a Gemini key; the Ask BuildGuard feature requires one. You can explore the code and run the demonstration from the BuildGuard GitHub repository. For me, submitting BuildGuard was a useful milestone in bringing construction experience into software development. It gave me a working way to test an idea: follow the evidence behind a payment request, make the checks explicit and explain the result. I would welcome feedback from construction managers, engineers, quantity surveyors, procurement teams and developers. Which records and approval steps would a tool like this need to understand in your projects?</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>