<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Blog on Luiz Bon</title>
    <link>https://luizbon.com/blog/</link>
    <description>Recent content in Blog on Luiz Bon</description>
    <generator>Hugo -- 0.165.0</generator>
    <language>en-AU</language>
    <copyright>Luiz Bon</copyright>
    <lastBuildDate>Sun, 30 Aug 2026 19:22:04 +1000</lastBuildDate>
    <atom:link href="https://luizbon.com/blog/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>An MCP registry isn&#39;t enough. You need a review gate too</title>
      <link>https://luizbon.com/blog/mcp-registry-needs-a-review-gate/</link>
      <pubDate>Fri, 28 Aug 2026 09:00:00 +1000</pubDate>
      <guid>https://luizbon.com/blog/mcp-registry-needs-a-review-gate/</guid>
      <description>Why an MCP registry alone is not enough: adding an agentic security review gate in CI that checks what an MCP server actually does, not just whether it is on the approved list.</description>
      <content:encoded><![CDATA[<p>I wrote about <a href="/blog/setup-mcp-registry">setting up an MCP Registry with Azure API Center</a> last year. That post covers the mechanics: register your MCP servers, expose an endpoint, point Copilot at it, restrict access to registry-only. It works, and it&rsquo;s a real control. But a registry alone answers one question: is this server on the approved list? It doesn&rsquo;t answer the harder one: should it be.</p>
<p>That second question is what an agentic security review is for.</p>
<h2 id="the-gap-a-static-registry-leaves-open">The gap a static registry leaves open</h2>
<p>A registry is a list someone maintains. Someone has to decide what goes on it, and that decision usually happens once, at onboarding time. The problem is that an MCP server&rsquo;s behaviour isn&rsquo;t fixed at onboarding. It can change with an update, expose a tool it didn&rsquo;t before, or request a data scope nobody reviewed the second time around. A registry checks membership. It doesn&rsquo;t check behaviour.</p>
<p>The obvious fix is a manual review before every server (or update) goes on the list. It doesn&rsquo;t scale. Review capacity stays flat while the number of servers and updates keeps growing, and a slow review queue is indistinguishable from a &ldquo;no&rdquo; to an engineer trying to ship this sprint. Slow the queue down enough and people stop asking, which brings back the exact shadow-tooling problem the registry was meant to solve.</p>
<h2 id="putting-the-review-in-ci-instead">Putting the review in CI instead</h2>
<p>We run the security review as a CI step, in the same pipeline that already runs tests and static analysis, triggered whenever an MCP server is added or updated. An agent checks the server&rsquo;s declared scopes against what it actually requests at runtime, looks at outbound network calls, and confirms the tool surface it exposes matches what it claims to expose. A failing review blocks the merge.</p>
<p>That timing matters more than the checks themselves. Putting the review in CI means it fires at the point a real decision gets made, a merge to a branch that will actually run, rather than at a hypothetical &ldquo;can I use this&rdquo; moment that may or may not turn into real usage. An engineer can pull a server down and try it locally without waiting on anyone. The review only has an opinion once there&rsquo;s something worth reviewing.</p>
<h2 id="what-this-costs">What this costs</h2>
<p>Nothing here is free. Someone can spend an afternoon on a server that fails review a day later, which is a worse experience than knowing up front. We accepted that trade deliberately. Wasted local experimentation is a smaller cost than either unreviewed tooling sitting in production or a review queue so slow that people route around it.</p>
<h2 id="where-this-sits-in-the-wider-conversation">Where this sits in the wider conversation</h2>
<p>Security and governance around agentic tooling dominated the conversation at RSAC 2026 and the MCP Dev Summit this year, and most of that conversation comes from platform teams at large tech companies or from security vendors. Less of it comes from engineering leaders at mid-size, regulated companies who built a governance layer because they needed one operating day to day, not because it&rsquo;s the product. That&rsquo;s the gap this post and the last one are trying to close from our side of the fence.</p>
<p>If you&rsquo;ve built something similar, or hit different failure modes putting a review gate in front of MCP adoption, I&rsquo;d like to hear about it.</p>
]]></content:encoded>
    </item>
    <item>
      <title>How to Set Up an MCP Registry for GitHub Copilot</title>
      <link>https://luizbon.com/blog/how-to-set-up-an-mcp-registry-for-github-copilot/</link>
      <pubDate>Mon, 13 Oct 2025 11:15:28 +0000</pubDate>
      <guid>https://luizbon.com/blog/how-to-set-up-an-mcp-registry-for-github-copilot/</guid>
      <description>A step-by-step guide to standing up an MCP Registry with Azure API Center so GitHub Copilot can only reach approved MCP servers.</description>
      <content:encoded><![CDATA[<h2 id="introduction">Introduction</h2>
<p>As organizations adopt AI-powered development tools like GitHub Copilot, maintaining security and governance becomes increasingly critical. The Model Context Protocol (MCP) enables Copilot to connect with external tools and data sources, but without proper controls, this connectivity can pose security risks. <strong>An MCP Registry provides enterprises with centralized control over which MCP servers and APIs their developers can access</strong>, ensuring that sensitive data and systems remain protected while still leveraging AI capabilities.</p>
<p>By implementing an MCP Registry, organizations can:</p>
<ul>
<li><strong>Control access</strong>: Restrict Copilot to only approved, vetted MCP servers</li>
<li><strong>Maintain compliance</strong>: Ensure all AI-enhanced development activities align with security policies</li>
<li><strong>Monitor usage</strong>: Track which APIs and tools are being accessed through Copilot</li>
<li><strong>Protect sensitive data</strong>: Prevent accidental exposure of proprietary APIs or internal systems</li>
</ul>
<p>In this guide, we&rsquo;ll walk through setting up an MCP Registry using Azure API Center and configuring GitHub Copilot to use it, giving your organization the security controls needed for safe AI-assisted development.</p>
<h2 id="part-1-set-up-an-mcp-registry-with-azure-api-center">Part 1: Set Up an MCP Registry with Azure API Center</h2>
<p>First, we&rsquo;ll follow the steps outlined in the <a href="https://learn.microsoft.com/en-us/azure/api-center/register-discover-mcp-server">official Microsoft documentation</a> to create an MCP-compatible API registry. This involves using Azure API Center, which can serve as a fully-featured MCP server.</p>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li><strong>An Azure subscription</strong> with contributor-level access or higher. If you don&rsquo;t have one, you can <a href="https://azure.microsoft.com/free/">create a free account</a> which includes $200 in credits for 30 days.</li>
<li><strong>Permissions to create resources</strong> in your Azure subscription, specifically the ability to create Azure API Center instances in your chosen resource group.</li>
<li><strong>Basic familiarity with the Azure Portal</strong> and navigating Azure resource management interfaces.</li>
<li><strong>(Optional) Azure CLI installed</strong> for automation or scripting purposes. You can install it following the <a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli">official guide</a>.</li>
</ul>
<p><strong>Estimated time to complete:</strong> 15-20 minutes</p>
<h3 id="steps">Steps</h3>
<ol>
<li>
<p><strong>Create an Azure API Center</strong>:</p>
<ul>
<li>Navigate to the Azure portal and search for &ldquo;API Center&rdquo;.</li>
<li>Click &ldquo;Create&rdquo; and fill in the required details for your new API Center instance.</li>
</ul>
</li>
<li>
<p><strong>Register MCP Servers</strong>:</p>
<ul>
<li>Once your API Center is deployed, you can start registering your existing MCP-compliant servers.</li>
</ul>
</li>
<li>
<p><strong>Enable API Center Portal</strong>:</p>
<ul>
<li>Under the &ldquo;API Center Portal&rdquo; &gt; &ldquo;Settings&rdquo; section, enable the portal. This will not only allow you to manage and view your registered MCP servers through a user-friendly interface, but also ensure that the MCP endpoint is properly configured and accessible.</li>
<li>In the Visibility section, check the option &ldquo;Allow &ldquo;anonymous&rdquo; access&rdquo;, otherwise GitHub Copilot won&rsquo;t be able to access the MCP registry.</li>
</ul>
</li>
<li>
<p><strong>Expose the MCP Endpoint</strong>:</p>
<ul>
<li>Azure API Center automatically provides an MCP-compatible endpoint. You can find this endpoint URL in the API Center&rsquo;s overview page in the Azure portal. It will look something like this: <code>https://&lt;your-api-center-name&gt;.data.&lt;location&gt;.azure-apicenter.ms/workspaces/default</code>.</li>
</ul>
</li>
</ol>
<p>By the end of this part, you will have a functional MCP server URL ready to be used by clients like GitHub Copilot.</p>
<h2 id="part-2-register-the-mcp-registry-in-github-copilot">Part 2: Register the MCP Registry in GitHub Copilot</h2>
<p>Now that you have your MCP server, you need to configure GitHub Copilot to use it. This is done by defining MCP Server access in your GitHub organization or enterprise settings, as detailed in the <a href="https://docs.github.com/en/copilot/how-tos/administer-copilot/configure-mcp-server-access">GitHub documentation</a>.</p>
<h3 id="prerequisites-1">Prerequisites</h3>
<p>Before configuring GitHub Copilot, verify you have:</p>
<ul>
<li><strong>Organization owner or enterprise administrator role</strong> in your GitHub organization. If you&rsquo;re unsure of your role, check your organization&rsquo;s &ldquo;People&rdquo; settings.</li>
<li><strong>GitHub Copilot Business or Enterprise subscription</strong> active for your organization. GitHub Copilot Individual subscriptions do not support MCP registry configuration.</li>
<li><strong>The MCP endpoint URL</strong> from Part 1 (format: <code>https://&lt;your-api-center-name&gt;.data.&lt;location&gt;.azure-apicenter.ms/workspaces/default</code>).</li>
<li><strong>Access to your GitHub organization settings</strong>, specifically the &ldquo;Copilot&rdquo; section under organization settings.</li>
</ul>
<p><strong>Note:</strong> Changes to MCP server policies may take up to 15 minutes to propagate to all users in your organization.</p>
<p><strong>Estimated time to complete:</strong> 5-10 minutes</p>
<h3 id="steps-1">Steps</h3>
<ol>
<li>
<p><strong>MCP servers policy</strong>:</p>
<ul>
<li>Setup MCP servers policy to <strong>Enabled</strong></li>
</ul>
</li>
<li>
<p><strong>MCP Registry URL</strong>:
The MCP Registry URL is an optional field.</p>
<ul>
<li>You can enter the MCP endpoint URL you obtained from your Azure API Center in Part 1.</li>
</ul>
</li>
<li>
<p><strong>Restrict MCP access to registry servers</strong>:</p>
<ul>
<li>Set this to <strong>Registry only</strong> to ensure that Copilot only accesses the APIs you have registered.</li>
</ul>
</li>
</ol>
<h2 id="conclusion">Conclusion</h2>
<p>You&rsquo;ve now successfully set up an MCP Registry using Azure API Center and integrated it with GitHub Copilot. Your developers can now leverage your organization&rsquo;s API definitions directly in their coding environment.</p>
<h3 id="next-steps">Next Steps</h3>
<ul>
<li>Register additional APIs in your API Center</li>
<li>Create documentation for your team on using the MCP-enhanced Copilot</li>
<li>Set up monitoring and analytics for API discovery usage</li>
<li>Explore advanced MCP features like custom tools and prompts</li>
</ul>
<h2 id="additional-resources">Additional Resources</h2>
<ul>
<li><a href="https://learn.microsoft.com/azure/api-center/">Azure API Center Documentation</a></li>
<li><a href="https://spec.modelcontextprotocol.io/">Model Context Protocol Specification</a></li>
<li><a href="https://docs.github.com/copilot">GitHub Copilot MCP Integration</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Are you prepared for your next job interview?</title>
      <link>https://luizbon.com/blog/are-you-prepared-for-your-next-job-interview/</link>
      <pubDate>Mon, 23 Sep 2019 11:47:51 +0000</pubDate>
      <guid>https://luizbon.com/blog/are-you-prepared-for-your-next-job-interview/</guid>
      <description>Why technical interviews exist and how interviewers actually evaluate candidates, from someone who has sat on both sides of the table.</description>
      <content:encoded><![CDATA[<h2 id="are-you-prepared-for-your-next-job-interview">Are you prepared for your next job interview?</h2>
<p>Have you ever failed in a technical interview? I bet 100% of the readers will say yes unless you never did one.
This article is not to teach you to succeed in a technical interview but to explain why they exist and how interviewers evaluate candidates.</p>
<blockquote>
<p><em>Disclaimer</em>: All information here is based on my experience and does not reflect the truth as each company or person can have different opinions.</p>
</blockquote>
<p>What I&rsquo;m going to cover here is:</p>
<ul>
<li>Why do companies do technical interviews</li>
<li>The interviewer</li>
<li>Candidates</li>
<li>Hiring processes</li>
</ul>
<h2 id="why-do-companies-do-technical-interviews">Why do companies do technical interviews</h2>
<p>There&rsquo;s no regulation on the IT industry like on other as Medicine where professionals need to pass a test and prove they&rsquo;ll not kill someone.
Unless you&rsquo;re making a medical app or coding an aeroplane computer, you&rsquo;re probably not putting anyone&rsquo;s life in danger. You&rsquo;ll most likely write code for a website or similar experience.</p>
<p>Even if there was a regulatory entity, the IT industry is so broad and fast-evolving that professionals will need to update their tests regularly.  Also, by the time the test is ready, the technology is already outdated.
To make sure a candidate know what their CV&rsquo;s states, the best option for companies is to do their own tests.</p>
<p>To access the candidates&rsquo; skills the companies need someone to run those tests, that is when the interviewer comes into play.</p>
<h2 id="the-interviewer">The interviewer</h2>
<p>Just thinking about interviewer most of the people will think about someone smart and want to make you fail.</p>
<p>When the interview is with more than one interviewer, there&rsquo;s always the good cop and the bad cop.</p>
<p>But this image needs to be changed. The interviewer is there to be your friend and wants you to succeed.</p>
<p>If a candidate is called to an interview is because the company already identified potential and it is possible to hire you. So failing candidates for the sake of having fun doesn&rsquo;t make sense as is expensive to keep doing interviews while the interviewer could be working on something else.</p>
<p>As a candidate, you are also doing an interview, you&rsquo;re evaluating how the interviewer behaves. That behaviour is probably how the company culture is, so if you don&rsquo;t identify yourself with the interviewer, you&rsquo;ll possibly not adapt to the company&rsquo;s culture.</p>
<p>People are different and have different likings, to don&rsquo;t feel bad if you don&rsquo;t identify yourself with the interviewer or company. This simply wasn&rsquo;t your best option, so it is better to move on. Take the opportunity to learn from the experience and apply to your next interview.</p>
<h2 id="candidates">Candidates</h2>
<p>This topic is in plural on purpose, because I&rsquo;m going to mention how I identify a good candidate, but more important than that is how to identify a great candidate.</p>
<p>I can enumerate a few skills to help me find good candidates.</p>
<ul>
<li><strong>Knowledge</strong> - the candidate will show excellent expertise on technologies</li>
<li><strong>Communication</strong> - even people thinking that IT professionals work on their computers all the time, communication is vital for them to work with stakeholders and colleagues. No one works alone.</li>
<li><strong>Experience</strong> - it is essential to have experience on the tech stack they work with.</li>
<li><strong>Problem solver</strong> - humans are problem solvers by nature, and IT professionals take this to the next level by scaling the solutions.</li>
</ul>
<p>Any candidate who can present those skills is considered a good candidate, but we can find better candidates if we evaluate a different set of skills.</p>
<ul>
<li><strong>Learner</strong> - a candidate who presents learning skills can improve their knowledge with time.</li>
<li><strong>Curious</strong> - a curious person will never agree to repeat the same work over the years, they&rsquo;ll always try to investigate and experiment new things.</li>
<li><strong>Teacher</strong> - there&rsquo;s no point in learning new things if you can&rsquo;t share your knowledge. So sharing is an excellent way to learn and upskill other people.</li>
<li><strong>Passionate</strong> - when someone has a passion for what they do, they&rsquo;ll never say TGIF because they love to work. There are no impossible challenges for passionate people.</li>
</ul>
<p>Now that we know what to identify on the right candidate, let&rsquo;s see how we can do that.</p>
<h2 id="hiring-processes">Hiring processes</h2>
<p>Usually, companies are very creative in their hiring processes, the problem with that is that they start to be complicated.</p>
<p>When a process is too complicated, it takes time, leading the candidate to withdraw. With the competitive market, we live nowadays, we need to be quick to hire the best candidates. Unless you are one of the major IT brands in the world.</p>
<p>So far, I worked for two companies as an interviewer. Perhaps I am biased, but their hiring processes are straightforward.</p>
<p>The first one is composed of 5 steps.</p>
<ul>
<li><strong>Technical puzzle</strong> - this is an in-house fully automated puzzle where the candidate generates a token, write their code and submit to the system. There&rsquo;s no human interaction, hence there are no costs to filter candidates who do not have the minimum experience.</li>
<li><strong>Live coding challenge</strong> - remote 30-minute code exercise where the candidate will use their own computer and IDE with the opportunity to show their coding skills. Usually, the task is to debug a broken app.</li>
<li><strong>Technical interview</strong> - remote or in-person chat about the candidate&rsquo;s technical knowledge. This chat will most likely be driven by the candidate, depending on how they answer the questions.</li>
<li><strong>Management interview</strong> - this stage is non-technical with a manager and a people &amp; culture person. They&rsquo;ll make sure the candidate is aligned with the company values.</li>
<li><strong>Offer!</strong></li>
</ul>
<p>That process is pleasant, straightforward, but it lacks a formal way to identify great candidates, relying only on interviewers feeling.</p>
<p>The second process has a significant step to try to identify the great candidate skills.</p>
<ul>
<li><strong>Phone screening</strong> - as the name says, this is a phone call where the interviewer will try to filter out the candidates who don&rsquo;t have minimal experience.</li>
<li><strong>Technical interview</strong> - this step can take up to 1.5 hours and is composed of a code challenge and technical discussion.</li>
<li><strong>Behavioural interview</strong> - that&rsquo;s when the interviewer is focused on identifying great candidate skills with non-technical questions.</li>
<li><strong>Cultural interview</strong> - interviewers from a different department will access the candidate based on the company&rsquo;s values to make sure they are a good fit.</li>
<li><strong>Offer!</strong></li>
</ul>
<p>As you can see, both processes are simple and straightforward, they also have their flaws.</p>
<p>Now you&rsquo;re probably asking yourself if I know those processes have flaws and know which part is better on each one. Why not change and make a better one?</p>
<p>Changing a hiring process is not easy, there&rsquo;s a lot of people involved, and you need to justify why it should be changed and how to improve. Later you&rsquo;ll need to evaluate if the results are valid or not and continue adapting.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The poor man&#39;s Progressive Web App</title>
      <link>https://luizbon.com/blog/the-poor-mans-progressive-web-app/</link>
      <pubDate>Tue, 31 Jul 2018 19:41:37 +1000</pubDate>
      <guid>https://luizbon.com/blog/the-poor-mans-progressive-web-app/</guid>
      <description>Turning a spreadsheet request from my father into an offline-capable Progressive Web App with no framework and no build step.</description>
      <content:encoded><![CDATA[<h2 id="a-bit-of-context">A bit of context</h2>
<p><a href="#solution"><em>I don&rsquo;t care about the context, show me the solution!</em></a></p>
<p>Last week my father sent me a message asking if I could build an electronic spreadsheet of the following image.</p>
<p><img alt="plan" loading="lazy" src="/img/poor-mans-pwa-1.jpeg"></p>
<p>Looking at the image I promptly reply with &ldquo;Can&rsquo;t you use Excel for this?&rdquo;</p>
<p>Then when I got home I opened my Excel and started to create a simple plan with the data from the image and that&rsquo;s when I saw the notes.</p>
<p><img alt="instructions" loading="lazy" src="/img/poor-mans-pwa-2.jpeg"></p>
<p>This note says &ldquo;Days = Difference between previous and actual date&rdquo;. This was the moment when my Excel skills failed me!
I tried to create a form input, but my research led me to some Visual Basic code and good old visual designer which I don&rsquo;t want to play with it anymore.
So I stopped and put some thinking on the issue.</p>
<ul>
<li>&ldquo;What are my options?&rdquo;</li>
<li>&ldquo;What do I know?&rdquo;</li>
<li>&ldquo;This thing need to work on an offline environment&rdquo; - There&rsquo;s no internet where he use this</li>
</ul>
<p>Building a desktop app means I&rsquo;ll need to create a setup, send to him, control the installation and updates. So is not a good option.
A web page seems simpler to solve the deployment, I&rsquo;m currently working with React, so no learning curve.</p>
<p>Based on this I though about doing an PWA app.</p>
<p>According to <a href="https://en.wikipedia.org/wiki/Progressive_Web_Apps">Wikipedia</a> this is a list of things your app should tick to be called as PWA.</p>
<ul>
<li><input disabled="" type="checkbox"> Progressive - Work for every user, regardless of browser choice because they’re built with progressive enhancement as a core tenet.</li>
<li><input disabled="" type="checkbox"> Responsive - Fit any form factor: desktop, mobile, tablet, or forms yet to emerge.</li>
<li><input disabled="" type="checkbox"> Connectivity independent - Service workers allow work offline, or on low quality networks.</li>
<li><input disabled="" type="checkbox"> App-like - Feel like an app to the user with app-style interactions and navigation.</li>
<li><input disabled="" type="checkbox"> Fresh - Always up-to-date thanks to the service worker update process.</li>
<li><input disabled="" type="checkbox"> Safe - Served via HTTPS to prevent snooping and ensure content hasn’t been tampered with.</li>
<li><input disabled="" type="checkbox"> Discoverable - Are identifiable as “applications” thanks to W3C manifests and service worker registration scope allowing search engines to find them.</li>
<li><input disabled="" type="checkbox"> Re-engageable - Make re-engagement easy through features like push notifications.</li>
<li><input disabled="" type="checkbox"> Installable - Allow users to “keep” apps they find most useful on their home screen without the hassle of an app store.</li>
<li><input disabled="" type="checkbox"> Linkable - Easily shared via a URL and do not require complex installation.</li>
</ul>
<p><a id="solution"></a>With that in mind, let&rsquo;s go to my solution.</p>
<h2 id="1-the-app">1. The App</h2>
<p>To create the app I used the <a href="https://github.com/facebook/create-react-app">Create React App</a> project from Facebook. The output is a basic app with a service worker in place.
So with a simple command I can check some items from the PWA list.</p>
<ul>
<li><input checked="" disabled="" type="checkbox"> Connectivity independent</li>
<li><input checked="" disabled="" type="checkbox"> Fresh</li>
</ul>
<p>This is really nice, but still have some checkboxes to tick.</p>
<h2 id="2-bootstrap">2. Bootstrap</h2>
<p>The app looks nice but it does nothing. Knowing I&rsquo;ll need to create a simple form for data input and a table to show the data, I&rsquo;ve pulled the <a href="http://getbootstrap.com/">Bootstrap 4</a> package and changed the inport from index.html.</p>
<p>And now I can tick one more item.</p>
<ul>
<li><input checked="" disabled="" type="checkbox"> Connectivity independent</li>
<li><input checked="" disabled="" type="checkbox"> Fresh</li>
<li><input checked="" disabled="" type="checkbox"> Responsive</li>
</ul>
<p>That&rsquo;s really nice, I have an app with 3 checkboxes ticked, but what about the functionality? It&rsquo;s time to write some code.</p>
<h2 id="3-react-app">3. React App</h2>
<p>I&rsquo;m not going into much detail here, it&rsquo;s not the intention of the post.</p>
<p>The app consists in a form with three fields pushing into an array and a table with the array contents.</p>
<p>All work fine, but what about persistence? I need to save this data somewhere.</p>
<h2 id="4-firebase">4. Firebase</h2>
<p>After a quick research I&rsquo;ve choosed <a href="https://firebase.google.com/">Firebase</a> to persist my data. It has a service called <a href="https://firebase.google.com/products/realtime-database/">Realtime Database</a> where I can save documents.
It&rsquo;s Javascript SDK has support for offline access and syncronization, so I don&rsquo;t lose my <strong>Connectivity independent</strong> tick.</p>
<p>The next challenge is to integrate Firebase SDK to React, that&rsquo;s when come in handy a simple package called <a href="https://github.com/tylermcginnis/re-base">Re-Base</a>, it&rsquo;s integration is very easy and I only needed to write a few lines of code to have everything in place.</p>
<p>After that integration I could say the app was ready. It was saving the data online and offline. Most importantly was the syncronization happening when connection was restablished.
Because the app have a service worker registered, I don&rsquo;t need to open the app to syncronize, it just works.</p>
<p>With the data being saved online, now was time to secure the data.</p>
<h2 id="5-authentication">5. Authentication</h2>
<p>To solve the Autentication issue Firebase came in handy again. It&rsquo;s SDK has auth integration with <a href="https://firebase.google.com/products/auth/">Firebase Authentication</a>, so I only needed to build a simple account creatiion form and a login page.
After that I configured my database security and it&rsquo;s all in place, each user has access only to their data.</p>
<p>To have another checkbox ticked I need to solve the hosting.</p>
<h2 id="6-cicd">6. CI/CD</h2>
<p>To deploy my code as easly as possible I choosed <a href="https://www.netlify.com/">Netlify</a> as it can integrate with a Git repository and do the deployment.
When configuring the app Netlify could identify it was a Create React App application and suggested me the build command. So it was a next&gt;next&gt;finish experience to have my site up and running on my custom domain with a <a href="https://letsencrypt.org/">Let&rsquo;s Encrypt</a> certificate.</p>
<p>After that I was able to tick on last checkbox</p>
<ul>
<li><input checked="" disabled="" type="checkbox"> Connectivity independent</li>
<li><input checked="" disabled="" type="checkbox"> Fresh</li>
<li><input checked="" disabled="" type="checkbox"> Responsive</li>
<li><input checked="" disabled="" type="checkbox"> Linkable</li>
<li><input checked="" disabled="" type="checkbox"> Safe</li>
</ul>
<h2 id="the-result">The Result</h2>
<p>At the end I spend less than a full day of work of my free time build a fully function app hosted on a HTTPS address with online database and offline capabilities.</p>
<p>If you&rsquo;re curious, below are a couple of screen shots. The source code can be found on <a href="https://github.com/luizbon/pesagem-ventania">Github</a>.</p>
<p><img alt="desktop view" loading="lazy" src="/img/poor-mans-pwa-3.jpeg">
<img alt="mobile view" loading="lazy" src="/img/poor-mans-pwa-4.jpeg"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Lessons learned from a conference ChatBot</title>
      <link>https://luizbon.com/blog/lessons-learned-from-a-conference-chatbot/</link>
      <pubDate>Sat, 02 Sep 2017 19:45:24 +1000</pubDate>
      <guid>https://luizbon.com/blog/lessons-learned-from-a-conference-chatbot/</guid>
      <description>What I learned building a conference chatbot for NDC Sydney with adaptive cards, QnAMaker, and Bing search as a fallback.</description>
      <content:encoded><![CDATA[<p>This year I worked as a volunteer at <a href="https://ndcsydney.com/">NDC Sydney</a>, and since I was involved with it, I decided to write a Bot to help attendees find sessions.</p>
<p>The ChatBot started simple answering questions related to sessions and speakers. It returns an <a href="http://adaptivecards.io/">adaptive card</a> with all information about each session.</p>
<p>Having all sessions wasn&rsquo;t enough, so I added integration with <a href="https://qnamaker.ai/">QnAMaker</a>, just in case a user asks about something not related to the sessions.</p>
<p>At this point, I wasn&rsquo;t happy yet, so I went one step further and added integration with <a href="https://azure.microsoft.com/en-us/services/cognitive-services/bing-web-search-api/">Bing search</a> to make sure the user will always receive an answer.</p>
<p>So far so good, what can go wrong? I was using adaptive cards, the content looked great, all information was there, I was covering FAQs and a fallback to Bing search.</p>
<p>Before the conference starts, I asked my colleagues to test the Bot, is always good to ask someone else test your code. The testing data improved the LUIS model, and answers get better.</p>
<p>That&rsquo;s when I started to realise that I needed to improve some things. The first one was the responsiveness. Yes, a ChatBot needs to be responsive. It needs to work on desktop and mobile since I wasn&rsquo;t integrating with any app, the web interface required to be responsive.</p>
<p><em>So first tip</em>: <strong>A ChatBot will not save you from the multi resolution devices issue, it is a lot simpler to solve though.</strong></p>
<p>With the responsiveness solved, I figured out another problem. The conference agenda has changed. Yes, this is an issue, cause I decided to use a local JSON file with all the data, this means I needed to check the whole agenda and update my file, luckily it didn&rsquo;t change much, and it was easy to update.</p>
<p>At this point, I was pretty confident with the Bot, from all the feedback I received from my colleagues the major ones were easy to fix, and others were just a case to train the <a href="https://www.luis.ai/">LUIS</a> model. So I started to make improvements and have better cards which show more data from the speaker.</p>
<p>When the conference started, and I was happy with the usage, till I find the first issue. The agenda has changed again. I just figured out when an attendee came to me asking about a session supposed to be in a room but was a different one. I promptly checked with the bot and the data was matching with his printed agenda, but after checking the website, I realised it was wrong again. At this point how do I update the agenda without a laptop? No luck here, I tried to stop thinking about it and enjoyed the conference. We can&rsquo;t win all the time.</p>
<p>On the next day, I was free in the morning, so I brought my laptop and updated the agenda quickly, that&rsquo;s when I realised that having too much data from a session wasn&rsquo;t working well, sometimes the results weren&rsquo;t displaying correctly.</p>
<p><em>Here it comes the next tip</em>: <strong>When showing multiple results, make sure they all have similar content.</strong></p>
<p>This day I missed the first session working on the result cards and added another result view based on the speaker. With the new cards, the result was consistent, and the user could click on a button to show extra information.</p>
<p>Overall the experience was positive, and I&rsquo;ll do it again, with some different decisions.</p>
<p><em>And one last tip</em>: <strong>A conference agenda is always changing, so is the website does not use an API, make sure you have an easy way to update your data.</strong></p>
]]></content:encoded>
    </item>
  </channel>
</rss>
