[{"content":"I\u0026rsquo;m a Senior Data Analyst with over 8 years of experience in data analysis, data administration, and data engineering. I leverage my MBA in Information Management and Business Intelligence to organize data flows, create visualizations, and support decision-making. My goal is to use data to solve complex problems, optimize processes, and generate insights that drive business growth and customer satisfaction.\nSome highlights from my career:\nReduced lead generation time from 3 hours to 20 minutes in several high-impact scenarios Led data migration efforts from relational and KV databases to BigQuery, ensuring scalability and seamless integration Built dashboards in Tableau and Looker Studio to track user interactions, conversion rates, and error detection Helped a risk team move from daily batch data transfers to near real-time, under PCI-DSS compliance requirements Defined data storage solutions for production applications and wrote ETL scripts for multi-source pipelines Monitored query performance and optimized queries, indexes, and partitions across multiple database engines I\u0026rsquo;ve worked in fintech, healthcare, and government, dealing with high-stakes data at scale.\nTools \u0026amp; technologies: BigQuery, SQL, Tableau, Looker Studio, Power BI, GCP, Azure, AWS, PostgreSQL, Oracle, Cassandra, MongoDB, REDIS\n","date":"4 June 2026","permalink":"https://adau.to/en/about/","section":"Adauto Meira","summary":"","title":"About"},{"content":"","date":null,"permalink":"https://adau.to/en/","section":"Adauto Meira","summary":"","title":"Adauto Meira"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/ai/","section":"Tags","summary":"","title":"Ai"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/estimation/","section":"Tags","summary":"","title":"Estimation"},{"content":"I had a GitHub repository called fp-control that was originally a Flask API deployed on AWS Lambda. It was not doing much. I decided to repurpose it entirely and turn it into something I actually wanted to use: a vendor-agnostic AI skill for planning software systems using Function Point Analysis.\nThe fact that it started as a dedicated application is worth noting. A well-structured skill can replace a surprising number of lightweight tools — the trade-off is that you become dependent on an agent subscription cost, or on the heavier lift of running a local LLM with enough capacity to follow complex instructions reliably. A local model gives you more control and, arguably, more room for unconventional ideas since you are not working within a commercial service\u0026rsquo;s guardrails. But for most use cases, a hosted agent with a good skill file is the faster path.\nWhat is a skill, exactly? #In the context of AI coding assistants, a skill is a Markdown file that an agent reads and follows as a set of instructions. Claude Code calls them commands; Cursor calls them rules; Windsurf calls them memories. The format varies slightly, but the idea is the same — you write the instructions once and the agent knows how to behave for that task in every future session.\nThe challenge with skills is distribution. If I write one for Claude Code, it only works there. I wanted something that any agent could pick up and use.\nThe auto-install pattern #The first design decision was to make the skill install itself. When an agent reads fp-control.md for the first time, the file\u0026rsquo;s own instructions tell it to detect which platform it is running on and copy itself to the appropriate global configuration directory. Claude Code gets ~/.claude/commands/fp-control.md. Cursor gets ~/.cursor/rules/fp-control.mdc. Windsurf gets its own path. Any other agent is instructed to use its platform\u0026rsquo;s equivalent.\nThe user never has to think about setup again after the first read. If they trust the agent to do it automatically, it just works. If they prefer to do it manually, the README includes a table with the exact command for each platform.\nThe Function Point Analysis workflow #Once installed, invoking /fp-control starts an IFPUG Function Point Analysis session. The skill walks the user through eight steps:\nDefine the system boundary — what is inside, what is outside Identify Internal Logical Files (ILF) — data the system owns and maintains Identify External Interface Files (EIF) — external data the system reads but does not maintain Count External Inputs (EI) — write operations that create, update, or delete internal data Count External Outputs (EO) — reports and calculated results sent outside the boundary Count External Inquiries (EIQ) — read-only lookups with no derived processing Calculate Unadjusted Function Points and produce a planning summary Optionally save the analysis as a structured Markdown file and generate an HTML report The skill asks one topic at a time, reasons through RET, DET, and FTR counts from the user\u0026rsquo;s descriptions when they are unsure, and keeps a running tally visible throughout. It also detects the language the user writes in and conducts the entire session — including the HTML output — in that language.\nRunning it on a real system #To test the skill, I ran a full FPA session for a multi-company platform with role-based access and a professional assignment model. The kind of system that, on paper, feels straightforward but quickly reveals its depth once you start counting what it actually does.\nThe analysis produced 329 Unadjusted Function Points across 74 items: 13 Internal Logical Files (91 FP), no External Interface Files, 33 External Inputs (111 FP), 12 External Outputs (62 FP), and 16 External Inquiries (65 FP). At typical industry benchmarks, that translates to roughly 4,600 hours of development effort — a concrete baseline before a single line of code is written.\nThe HTML report #At the end of the session the skill generates a self-contained HTML file with no external dependencies. Everything — CSS, JavaScript, data — is inlined. The report is structured as a tabbed interface: an Overview tab with the system boundary, a bar chart, and the UFP summary, followed by one tab per function type (ILF, EIF, EI, EO, EIQ) and a final Effort \u0026amp; Risks tab.\nEach function-type tab includes a complexity reference card showing the IFPUG matrix for that type, and a full item table with a \u0026ldquo;Rule applied\u0026rdquo; column that makes the reasoning transparent — for example, FTR 2, DET 5–15 → Avg. Anyone reading the report can trace exactly how each item was rated.\nThe report also has a dark/light mode toggle and two print buttons: one that prints the full report in light mode regardless of the current theme, and a second that prints a simplified summary showing only the Overview tab.\nSession continuity with .fpa.md #One limitation of working with AI agents is that sessions end. Compaction truncates context. A full FPA session for a moderately complex system involves dozens of items across five function types — not something you want to reconstruct from memory.\nThe skill addresses this by saving the analysis as a .fpa.md file. The file has two parts: a YAML frontmatter block with all structured data (every item, its counts, complexity, and FP value), and a human-readable markdown body with the full planning summary below it. When the user opens a new session and references the file, the agent reads the frontmatter and offers to resume from exactly where things were left off — presenting the summary, updating specific items, or going straight to HTML generation.\nOne file serves both purposes: machine-readable enough for an agent to restore state, human-readable enough to open in any editor and understand at a glance.\nWhy Function Points still matter #There is a reasonable question about whether measuring functional size is still relevant when AI can generate code faster than ever. My view is that it matters more, not less. AI accelerates implementation but does not shrink requirements. A system with 300 Function Points has the same functional complexity whether it takes a team of ten three months or a solo developer with an AI assistant two weeks. The scope is the same; only the productivity changed.\nFunction Points give you a technology-agnostic baseline for that scope — one that is comparable across projects, defensible in contracts, and useful for recalibrating benchmarks as AI-assisted development productivity data accumulates. Knowing what you are asking the AI to build, and how much of it, is still the first step before asking it to build anything.\nThe repository is at github.com/adautomeira/fp-control and is released under the MIT license.\n","date":"4 June 2026","permalink":"https://adau.to/en/posts/fp-control-an-ai-skill-for-function-point-analysis/","section":"Posts","summary":"How I replaced a Flask app with a vendor-agnostic AI skill that guides any agent through IFPUG Function Point Analysis — including a self-contained HTML report, dark mode, and session continuity.","title":"fp-control: Function Point Analysis as an AI Skill, Not an Application"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/function-points/","section":"Tags","summary":"","title":"Function-Points"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/planning/","section":"Tags","summary":"","title":"Planning"},{"content":"","date":null,"permalink":"https://adau.to/en/posts/","section":"Posts","summary":"","title":"Posts"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/data-engineering/","section":"Tags","summary":"","title":"Data-Engineering"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/etl/","section":"Tags","summary":"","title":"Etl"},{"content":"Imagine you have a bookshelf full of books. At some point, you need to move those books to a new shelf. The old bookshelf and the new one have different structures, and you need to organise the books so they fit properly in the new space.\nIn that scenario, you will have to select what actually goes to the new shelf, respecting its limits and the final organisation of the books according to the new structure.\nThis analogy illustrates the steps required to migrate data between different databases.\nThe topics presented here are the result of a data migration project between databases of different technologies, different structures, different business rules, and a tight development and testing deadline. The goal is to show a \u0026ldquo;simple\u0026rdquo; workflow without relying on any specific technology beyond SQL itself. I don\u0026rsquo;t consider these steps the best possible strategy — just what I was able to do with what I had available.\nConsiderations #Things to observe before starting the migration:\nUnderstand the DBMS Limitations (Source and Target) #Understanding how the DBMS and its tools work will help anticipate problems that may occur during the migration. Some scripts, depending on how the database and the business are structured, can contain more than 1 million records, and not every tool or DBMS will be able to execute them. Some clients perform better than others, and some may perform better depending on the target DBMS. Other clients may have issues with the script\u0026rsquo;s locale configuration, potentially skipping some statements.\nBeyond the tooling, the DBMS itself can be a limiting factor. One common problem is how it processes scripts, to the point of locking up the server.\nIdentify the Structural Peculiarities of Each Database #Each table may have one or more dependencies (foreign keys or FKs). These dependencies affect the order in which data must be imported. In addition, tables containing enums and code data should be listed and handled before the main data. It is also necessary to check for duplicate or similar records across multiple sources to avoid redundancy.\nIndexes on source databases can speed up reading and generating intermediate files. On target databases, indexes may limit the number of records inserted or updated per second. In both cases, it is necessary to evaluate the need and impact of creating or removing them.\nAvoid Subselects with Inline Arguments #Subselects will sometimes be necessary. The issue arises when you need to use a column value to perform additional lookups — this significantly increases execution time. The solution is to transform that lookup into a dataset to be used as an argument in an IN clause. For example:\n-- Avoid: SELECT * FROM TABLE T WHERE id \u0026lt;\u0026gt; (SELECT id FROM TABLE2 T2 WHERE T.value = T2.value) -- Prefer: SELECT * FROM TABLE T WHERE id IN (SELECT id FROM TABLE2 T2 WHERE T2.value = argument) -- Even better: SELECT * FROM TABLE T WHERE EXISTS (SELECT id FROM TABLE2 T2 WHERE T2.value = id) Process #Create a \u0026ldquo;Composer\u0026rdquo; Script #A typical SQL script has the following structure:\nSELECT column1, column2 FROM table WHERE column3 = argument The Composer is a script structure that extracts data from the source database and formats the output in the pattern expected by the target database. For example:\nSELECT \u0026#39;INSERT INTO table (column1, column2) VALUES (\u0026#39;\u0026#39;\u0026#39; + source_column1 + \u0026#39;\u0026#39;\u0026#39;, \u0026#39;\u0026#39;\u0026#39; + source_column2 + \u0026#39;\u0026#39;\u0026#39;);\u0026#39; AS \u0026#34;-- TABLE\u0026#34; FROM table WHERE columnX = argumentY The result is a file ready to execute on the target database:\n-- TABLE INSERT INTO table (column1, column2) VALUES (\u0026#39;Value1\u0026#39;, \u0026#39;Value2\u0026#39;); INSERT INTO table (column1, column2) VALUES (\u0026#39;Value3\u0026#39;, \u0026#39;Value4\u0026#39;); Use Functions/Procedures for Critical Data #Some critical data may have duplicates, incomplete records, or require updates due to business rules. Functions and procedures allow you to control this data by creating auxiliary tables:\nSUCCESS_TABLE: records successfully saved data. FAILURE_TABLE: identifies inconsistent or duplicate records. SELECT \u0026#39;SELECT function(\u0026#39;\u0026#39;\u0026#39; + source_column1 + \u0026#39;\u0026#39;\u0026#39;, \u0026#39;\u0026#39;\u0026#39; + source_column2 + \u0026#39;\u0026#39;\u0026#39;);\u0026#39; AS \u0026#34;-- FUNCTION_TABLE\u0026#34; FROM table WHERE columnX = argumentY Split Results into Separate Files #To avoid a single file containing all INSERT statements — which is hard to manage or update — it is recommended to split records by table or business rule. Some of those separate files still reached 300MB in size.\nVerify That All Records Were Processed #There were cases where some records were not inserted due to encoding conflicts between the tool and the executed script, causing some records to be silently skipped. Verifying the record count after script execution will prevent unwanted surprises.\nFinal Thoughts #Point-in-time extractions with few records, from non-conventional data sources (CSV, Excel, etc.), with simple business models, can benefit from the workflow presented here.\nSome situations may allow the use of tools like Pentaho PDI or Airflow. In others, corporate policies will restrict access to target systems, requiring that all changes be made through scripts executed by credentialed personnel.\n","date":"1 December 2017","permalink":"https://adau.to/en/posts/how-to-do-a-simple-data-migration/","section":"Posts","summary":"A simple workflow for migrating data between different databases, without relying on specific technologies beyond SQL itself.","title":"How to Do a \"Simple\" Data Migration"},{"content":"","date":null,"permalink":"https://adau.to/en/tags/sql/","section":"Tags","summary":"","title":"Sql"},{"content":"","date":null,"permalink":"https://adau.to/en/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://adau.to/en/portfolio/","section":"Portfolio","summary":"","title":"Portfolio"}]