[{"data":1,"prerenderedAt":551},["ShallowReactive",2],{"content-en":3},{"id":4,"about":5,"education":11,"experience":25,"extension":66,"meta":67,"projects":68,"stem":549,"__hash__":550},"site\u002Fsite\u002Fen.yml",{"title":6,"paragraphs":7},"About me",[8,9,10],"I am a full stack developer working with Laravel, Vue, Livewire, TypeScript and PostgreSQL. I design and build whole web products, from the first requirements conversation with the client to deployment.","Since 2023 I have worked at Overclock Tech, delivering Laravel applications with Vue or Livewire. On larger projects I scope the work with the client and coordinate partner developers.","I am also doing a master's in Nanosciences at Universidade Franciscana, where I built AETHER, a Python pipeline with a FastAPI API and a Vue interface.",{"title":12,"items":13},"Education",[14,20],{"period":15,"title":16,"subtitle":17,"description":18,"link":19},"2025 – Present","Master's in Nanosciences","Universidade Franciscana","I research graph neural networks for screening green hydrogen catalysts.","\u002Fprojetos\u002Faether",{"period":21,"title":22,"subtitle":17,"description":23,"link":24},"2020 – 2024","Computer Science","Capstone project on an automated guided vehicle prototype for Industry 4.0 logistics.","https:\u002F\u002Ftfgonline.lapinf.ufn.edu.br\u002Fmedia\u002Fmidias\u002Ftfg2-mau_8CsAUZs.pdf",{"title":26,"cvButton":27,"cvHref":28,"items":29},"Experience","Full resume in PDF","\u002Fresume.pdf",[30,47,56],{"period":31,"title":32,"subtitle":33,"link":34,"description":35,"tags":36},"Oct 2023 – Present","Full Stack Developer","Overclock Tech","https:\u002F\u002Foverclk.tech","End-to-end web applications with Laravel, paired with Vue or Livewire depending on the project. I coordinate partner developers on larger engagements and scope the work directly with the client.",[37,38,39,40,41,42,43,44,45,46],"TypeScript","PHP","Laravel","Vue","Livewire","Nuxt","PostgreSQL","Docker","Tailwind CSS","Playwright",{"period":48,"title":49,"subtitle":50,"link":51,"description":52,"tags":53},"Feb – Aug 2023","Web Developer","Santa Maria City Hall","https:\u002F\u002Fwww.santamaria.rs.gov.br","Maintenance and development of the City Hall's internal and public systems, shipping features for the ticket management system, the Imposto Solidário program and CadÚnico-related systems.",[39,38,54,44,41,55],"MySQL","JavaScript",{"period":57,"title":58,"subtitle":59,"link":60,"description":61,"tags":62},"Sep 2022 – Feb 2023","IT Intern","National Social Security Institute","https:\u002F\u002Fwww.gov.br\u002Finss\u002Fpt-br","Computer maintenance, technical support and administration.",[63,64,65],"Maintenance","Repair","Support","yml",{},{"title":69,"intro":70,"contributionLabel":71,"highlightsLabel":72,"problemLabel":73,"requirementsLabel":74,"dataModelLabel":75,"stackLabel":76,"galleryLabel":77,"caseStudyLabel":78,"backLabel":79,"otherTitle":80,"otherItems":81,"items":102},"Selected work","A selection of digital products, public platforms and applied research where I contributed from strategy through delivery.","My contribution","Project highlights","The problem","Requirements","Data model","Technologies","Inside the product","Read the case study","Back to projects","More engineering projects",[82,93],{"period":83,"title":84,"description":85,"link":86,"image":87,"tags":88},"2024","Industrial Transport Vehicle Monitoring","A web system for managing and monitoring an Automated Guided Vehicle, integrating software, electronics and industrial automation.","https:\u002F\u002Fgithub.com\u002Fmauricioprb\u002Ftfg-agv-sistema","\u002Fprojetos\u002Fprojeto-sistema-agv.jpg",[89,37,90,91,92],"Next.js","tRPC","Prisma","MQTT",{"period":94,"title":95,"description":96,"link":97,"image":98,"tags":99},"2023","CSA, Food Safety Culture","Research software developed with UFN graduate and Nutrition programs to collect and analyze food-safety culture data.","https:\u002F\u002Fgithub.com\u002Flabedufn\u002Fculturanutri","\u002Fprojetos\u002Fprojeto-csa.png",[89,100,37,91,101],"Node.js","Zod",[103,161,214,264,326,389,444,512],{"id":104,"title":33,"accessNote":105,"contribution":106,"cover":107,"coverAlt":108,"dataModel":105,"description":109,"extension":66,"facts":110,"gallery":120,"highlights":135,"links":145,"meta":149,"order":150,"problem":151,"requirements":105,"slug":152,"stem":153,"summary":154,"tags":155,"__hash__":160},"projects\u002Fprojects\u002Fen\u002Foverclock-tech.yml",null,"I designed the brand as a system. Overclock Tech is the umbrella brand, and Systems and Games share the same mascot, changing only the color and the second line of the name. The colors come from the flame test, where the burning element changes the color of the fire, with sodium for Tech's yellow, selenium for Systems' blue and barium for Games' green. The three divisions' tones share the same luminance so none looks downgraded, and the contrast of every background pairing was measured. The result is 24 SVG logos, icons that hold up from 16 pixels and a 30-page brand manual. For the site, I built the interface with no component library. The ASCII art on the home page is drawn on an OffscreenCanvas inside a Web Worker, off the main thread. The site is static, with every route pre-rendered, light and dark themes, GSAP plus Lenis animation that respects the reduced-motion preference, and a contact form that sends email through Resend. The Playwright end-to-end tests include accessibility checks with axe.","\u002Fprojetos\u002Foverclock-home.webp","Overclock Tech home page with the headline 'We make tech. Overclocked.' over yellow ASCII art","Brand and company website for Overclock Tech, presenting its two divisions, Overclock Systems and Overclock Games, in Portuguese and English.",[111,114,117],{"label":112,"value":113},"Role","Brand, visual direction and development",{"label":115,"value":116},"Period","2026",{"label":118,"value":119},"Type","Brand and company website",[121,126,129,132],{"src":122,"caption":123,"w":124,"h":125},"\u002Fprojetos\u002Foverclock-marca-divisoes.webp","The umbrella brand and its two divisions, sharing one mascot and the colors of sodium, selenium and barium.",2560,1600,{"src":127,"caption":128,"w":124,"h":125},"\u002Fprojetos\u002Foverclock-marca-versoes.webp","Vertical lockups, avatars and app icons, drawn to hold up from 16 pixels.",{"src":130,"caption":131,"w":124,"h":125},"\u002Fprojetos\u002Foverclock-antes-home.webp","Before, the Overclock Labz site was a sales page for 14-day prototypes.",{"src":133,"caption":134,"w":124,"h":125},"\u002Fprojetos\u002Foverclock-antes-pacote.webp","Before, the offer was a single package with a prototype, hosting, a subdomain and 30 days of support.",[136,139,142],{"value":137,"label":138},"24","SVG logos, with a brand manual",{"value":140,"label":141},"2 divisions","Systems and Games under one brand",{"value":143,"label":144},"Web Worker","ASCII art off the main thread",[146],{"label":147,"href":34,"icon":148},"Visit website","ri:external-link-line",{},1,"The company started as Overclock Labz, a development studio, and grew into two divisions, software and games. The previous site, which I also built, only talked about prototypes. It needed a brand that could hold both divisions without either looking secondary, and a site with a page and a voice for each audience.","overclock-tech","projects\u002Fen\u002Foverclock-tech","The company website, covering its systems and games divisions.",[156,37,157,158,159,46],"Nuxt 4","Tailwind CSS v4","GSAP","Lenis","ruwfqGUi8pykFuRJSrZQgAnlHrjOscFIsZx__Gst4AU",{"id":162,"title":163,"accessNote":105,"contribution":164,"cover":165,"coverAlt":166,"dataModel":105,"description":167,"extension":66,"facts":168,"gallery":174,"highlights":190,"links":200,"meta":203,"order":204,"problem":205,"requirements":105,"slug":206,"stem":207,"summary":208,"tags":209,"__hash__":213},"projects\u002Fprojects\u002Fen\u002Flapinf.yml","LaPInf","I extracted the old site's content into Markdown and YAML files and rebuilt the site in Vue 3 with Vite SSG, which generates the HTML for every route and works without JavaScript. Each project got its own page with professors, students, partners, programs and INPI registrations, and the archive can be filtered by program, with the filter kept in the URL. Projects, notices, partners and FAQ entries are edited through Pages CMS without touching the code, and a Vite plugin validates every collection with Zod at build time, pointing to the source file when a field is invalid. Notices have publish, start and expiry times in Brasília time. The HTML ships with the notices that are live at build time and the browser re-evaluates the list every 30 seconds, so a notice goes up and comes down without a new deploy. Unit tests cover content, filters, pagination, credits and notice times, and the end-to-end tests run in Chromium with accessibility checks from axe.","\u002Fprojetos\u002Flapinf-home.webp","LaPInf home page with the headline 'Students apply what they learn in class to challenges brought by the community.'","The website for Universidade Franciscana's Computing Practice Lab, replacing a page built in 2019 from a Bootstrap template. It brings together the computing programs' project archive, the authorship of each project and its INPI registrations.",[169,171,172],{"label":112,"value":170},"Development",{"label":115,"value":116},{"label":118,"value":173},"Institutional website",[175,178,181,184,187],{"src":176,"caption":177,"w":124,"h":125},"\u002Fprojetos\u002Flapinf-acervo.webp","The archive gathers the programs' projects, with filters by program, the authorship of each one and a marker for the systems that are live.",{"src":179,"caption":180,"w":124,"h":125},"\u002Fprojetos\u002Flapinf-projeto.webp","Every project has its own page, with a description, access to the system and credits for faculty, students and partners.",{"src":182,"caption":183,"w":124,"h":125},"\u002Fprojetos\u002Flapinf-antes-home.webp","Before, the 2019 page built on the Bolt template, with Bootstrap and jQuery.",{"src":185,"caption":186,"w":124,"h":125},"\u002Fprojetos\u002Flapinf-antes-projetos.webp","Before, each project's credits opened in a modal, with no page or address of its own.",{"src":188,"caption":189,"w":124,"h":125},"\u002Fprojetos\u002Flapinf-antes-inpi.webp","Before, the INPI registrations were a collage of certificate images.",[191,194,197],{"value":192,"label":193},"34","projects in the archive",{"value":195,"label":196},"8","verifiable INPI registrations",{"value":198,"label":199},"No JavaScript","HTML generated for every route",[201],{"label":147,"href":202,"icon":148},"https:\u002F\u002Flapinf.ufn.edu.br",{},2,"The old site was a single HTML page built in 2019 on the Bolt template, with Bootstrap and jQuery, and maintained for seven years by editing the code directly. Projects had no address of their own, credits were free text scattered across cards, modals and even browser confirm dialogs, and the INPI registrations were a collage of certificate images, with no number you could copy or link to a project. People who assess the lab from outside, such as managers, partners and institutions, could not quickly understand what was built, by whom, and how to verify it.","lapinf","projects\u002Fen\u002Flapinf","Website for UFN's Computing Practice Lab.",[210,37,211,157,101,212,46],"Vue 3","Vite SSG","Pages CMS","Y80YxT66_OruPpizYncOziV59P7gdc5KEsdYl2Loa04",{"id":215,"title":216,"accessNote":105,"contribution":217,"cover":218,"coverAlt":219,"dataModel":105,"description":220,"extension":66,"facts":221,"gallery":227,"highlights":234,"links":244,"meta":252,"order":253,"problem":254,"requirements":105,"slug":255,"stem":256,"summary":257,"tags":258,"__hash__":263},"projects\u002Fprojects\u002Fen\u002Ffuse-ui.yml","FUSE UI","I defined the monorepo architecture and the two-layer design token system (primitive and semantic, in CSS), and wrote 82 components and 26 blocks on top of Reka UI's accessible primitives, with variants in CVA, plus charts and composables. I published the CLI to npm and maintain the development Storybook, the bilingual Nuxt documentation, with a props table generated from the component source and a theme generator, the 117 Vitest test files and versioning with Changesets.","\u002Fprojetos\u002Ffuse-ui-calendar.webp","FUSE UI documentation showing the Event Calendar component in month view","A Vue 3 component library on the registry\u002FCLI model, where the command copies the source into your project. You own the component and can edit it.",[222,224,225],{"label":112,"value":223},"Author and maintainer",{"label":115,"value":116},{"label":118,"value":226},"Component library",[228,231],{"src":229,"caption":230,"w":124,"h":125},"\u002Fprojetos\u002Ffuse-ui-button.webp","Every component documents a preview, the install command, usage, a props reference and accessibility notes.",{"src":232,"caption":233,"w":124,"h":125},"\u002Fprojetos\u002Ffuse-ui-docs.webp","The docs are a Nuxt site with search, light and dark themes, and content in Portuguese and English.",[235,238,241],{"value":236,"label":237},"82","components in the registry",{"value":239,"label":240},"26","ready-to-copy blocks",{"value":242,"label":243},"117","Vitest test files",[245,249],{"label":246,"href":247,"icon":248},"Read the docs","https:\u002F\u002Ffuseui.overclk.tech","ri:book-open-line",{"label":250,"href":251,"icon":148},"View on npm","https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@overclock\u002Ffuse-ui",{},3,"Libraries installed as a dependency solve the first day and get in the way of every day after, because any customization becomes a hack layered over someone else's CSS. FUSE UI inverts that logic and the component lands in your repository, with design tokens that let you retheme everything without touching a single component.","fuse-ui","projects\u002Fen\u002Ffuse-ui","Vue components that the CLI copies into your own project.",[210,37,259,157,260,261,42,262],"Reka UI","CVA","Vitest","Changesets","JC6GoAAUpMl9eePK5nglJRSmWoBlPqm_C4Ly_7ZlHU4",{"id":265,"title":266,"accessNote":105,"contribution":267,"cover":268,"coverAlt":269,"dataModel":105,"description":270,"extension":66,"facts":271,"gallery":277,"highlights":281,"links":291,"meta":295,"order":296,"problem":297,"requirements":298,"slug":316,"stem":317,"summary":318,"tags":319,"__hash__":325},"projects\u002Fprojects\u002Fen\u002Fdumphere.yml","Dumphere","The first version, from March 2026, used Laravel Reverb with Echo for presence events next to a Yjs server that kept rooms in memory only, deployed with Docker. In July I rewrote the sync layer to rely on Yjs alone, with the Node server requiring a token signed by Laravel and persisting snapshots in PostgreSQL, replaced Docker with deploys through Laravel Forge and went from 2 to 31 test files. Rich editing uses Tiptap, with a per-document local cache in IndexedDB. On the server, HTML is sanitized before it is stored, document creation and connections are rate-limited per IP, and a scheduler removes documents untouched for 30 days. The interface is bilingual and covered by Pest tests. I also evaluated the sync layer in a paper, comparing it with operational transformation and with periodic whole-document replacement, the model common in address-based editors. With automated clients typing at the same time, Dumphere preserved 100% of the words in every condition, including during disconnections, while whole-document replacement kept as little as 13% to 15% with eight clients.","\u002Fprojetos\u002Fdumphere-editor.webp","The Dumphere editor with a Markdown document, a code block and another participant's cursor","A public document editor with real-time collaboration, offline support and URL sharing, with no account required.",[272,274,275],{"label":112,"value":273},"Concept, architecture and development",{"label":115,"value":116},{"label":118,"value":276},"Side project",[278],{"src":279,"caption":280,"w":124,"h":125},"\u002Fprojetos\u002Fdumphere-home.webp","On the landing page, the address itself is the creation and sharing mechanism.",[282,285,288],{"value":283,"label":284},"100%","of words preserved with 8 concurrent clients",{"value":286,"label":287},"~101 ms","median for another client to see an edit, at 100 ms round trip",{"value":289,"label":290},"30 days","automatic expiry for untouched pages",[292],{"label":293,"href":294,"icon":148},"Open Dumphere","https:\u002F\u002Fdumphere.app",{},4,"Opening a shared space to write usually costs an account, an invite and a permissions setup. Dumphere reduces all of that to picking an address. The first visit creates the page, and anyone with the link is already editing alongside you.",[299,308],{"title":300,"items":301},"Functional",[302,303,304,305,306,307],"Create the page on the first visit to a valid path, with up to four segments and 100 characters.","Edit together in visual mode or in the Markdown source, with participants' cursors and presence.","Show the connection and save status.","Keep the content in the browser during network drops and sync when the connection returns.","Export the document as Markdown or HTML.","Remove the page after 30 days without visits.",{"title":309,"items":310},"Non-functional",[311,312,313,314,315],"Work with no account, authentication or deliberate collection of personal data.","Sanitize HTML on the server and cap it at 512 KB, with a 2 MB cap on the collaborative snapshot.","Rate-limit document creation, requests and collaborative connections per IP.","Keep document content and connection tokens out of the logs.","Meet WCAG 2.2 AA in light and dark themes, in Portuguese and English.","dumphere","projects\u002Fen\u002Fdumphere","Real-time collaborative editor that needs no account.",[320,321,210,322,323,43,324],"Laravel 13","Inertia","Tiptap","Yjs","Pest","Mt3ZD7RiXXAKus79jAajAeofj8mi3hQTNF64ZeNy53I",{"id":327,"title":328,"accessNote":329,"contribution":330,"cover":331,"coverAlt":332,"dataModel":333,"description":339,"extension":66,"facts":340,"gallery":347,"highlights":351,"links":361,"meta":362,"order":363,"problem":364,"requirements":365,"slug":382,"stem":383,"summary":384,"tags":385,"__hash__":388},"projects\u002Fprojects\u002Fen\u002Fclips.yml","Clips","Private repository","The first version, from December 2025, was built in Next.js with Prisma and already handled a fellow's month, but it had no invitations or user administration. In 2026 I rewrote the application in Laravel with Inertia and Vue and covered its rules with 68 Pest tests and 15 Vitest tests. The fill-month action places the weekly schedule on the days it applies and tops up every working day to the target with the default activities, rotating by priority, without ever changing a manual entry. The target accounts for national holidays and the ones the fellow adds, and the PDF report lists working days only. Access is invite-only with user administration, and deployment runs through Laravel Forge once the tests pass in CI.","\u002Fprojetos\u002Fclips-mes.webp","Clips month calendar with hours logged on every working day and the 84-hour total met",{"src":334,"srcDark":335,"caption":336,"w":337,"h":338},"\u002Fprojetos\u002Fclips-er.webp","\u002Fprojetos\u002Fclips-er-dark.webp","Each fellow owns their entries, weekly schedule, default activities and holidays, and the invitation stays apart from the account until the password is set.",2088,1068,"A web app where research fellows log their hours, fill the month automatically from their weekly schedule and default activities, and download the monthly report as a PDF.",[341,343,345],{"label":112,"value":342},"Concept and development",{"label":115,"value":344},"2025 – 2026",{"label":118,"value":346},"Web application",[348],{"src":349,"caption":350,"w":124,"h":125},"\u002Fprojetos\u002Fclips-atividades.webp","Default activities fill working days in rotation. High priority comes up three times, medium twice and low once.",[352,355,358],{"value":353,"label":354},"1 click","to fill the month",{"value":356,"label":357},"PDF","monthly report ready to hand in",{"value":359,"label":360},"Invite-only","access managed by administrators",[],{},5,"Every month a fellow has to hand in a report with the hours worked, day by day, until the scholarship workload is met. Building it by hand in a spreadsheet takes time, and it is easy to get working days, holidays and the monthly target wrong.",[366,373],{"title":300,"items":367},[368,369,370,371,372],"Register the fellowship details, the weekly schedule with a validity period, default activities with a priority and personal holidays.","Log each day's activities with start and end times.","Fill the month from the weekly schedule and the default activities, mornings first and then afternoons.","Generate the monthly PDF report.","Invite people by email, with a set-password link valid for 7 days, and block or unblock access.",{"title":374,"items":375},"Business rules",[376,377,378,379,380,381],"The daily target is the weekly workload divided by 5, and the monthly target is the daily target times the working days.","Working days run Monday to Friday, except national holidays and the ones the fellow adds.","Automatic filling never changes or overlaps a manual entry.","Priority sets how often each default activity is used (high 3, medium 2, low 1).","The report lists working days only, and hours on weekends and holidays are left out of the total.","There is no open sign-up.","clips","projects\u002Fen\u002Fclips","Hour tracking and monthly reports for research fellows.",[320,386,210,37,387,157,43,324],"Inertia 3","PrimeVue 5","Ojr2MPDm9GaOvFFOcJg6d9poDFgr_txriN8rJXbn9FA",{"id":390,"title":391,"accessNote":105,"contribution":392,"cover":393,"coverAlt":394,"dataModel":105,"description":395,"extension":66,"facts":396,"gallery":402,"highlights":414,"links":424,"meta":429,"order":430,"problem":431,"requirements":105,"slug":432,"stem":433,"summary":434,"tags":435,"__hash__":443},"projects\u002Fprojects\u002Fen\u002Faether.yml","AETHER","I built a reproducible pipeline for curation, training, comparison and explainability over 5,860 Catalysis Hub structures, evaluated on two splits, a random one and one that keeps bulk compositions apart between training and test, to measure how well models generalize to materials they have not seen. I compared four approaches on the same data (physicochemical descriptors with Extra Trees, SchNet trained from scratch, an MLP head on the frozen pretrained MACE-MP-0, and Extra Trees on MACE embeddings), reporting mean and standard deviation over 5 seeds. SHAP-based descriptor selection is done without leaking the test set, and the MAE difference between models comes with a bootstrap confidence interval. The best result, an ensemble of 5 SchNets, reaches an R² of 0.9734 and an MAE of 0.0585 eV. The models are served by a FastAPI API with a Vue 3 interface that estimates a structure's ΔG_H, and the software's INPI registration is in progress.","\u002Fprojetos\u002Faether-compare.webp","AETHER comparison screen showing the metrics of all four models side by side","An AI pipeline that estimates hydrogen adsorption energy and supports catalyst screening for green hydrogen production.",[397,399,400],{"label":112,"value":398},"Research and pipeline author",{"label":115,"value":344},{"label":118,"value":401},"Master's thesis",[403,406,410],{"src":404,"caption":405,"w":124,"h":125},"\u002Fprojetos\u002Faether-triagem.webp","Screening starts on a periodic table that only enables elements present in the dataset, then ranks candidates by how close they sit to the Sabatier optimum.",{"src":407,"caption":408,"w":124,"h":409},"\u002Fprojetos\u002Faether-abstract.webp","The study design, from DFT-computed adsorption through transfer learning to the final candidate screening.",984,{"src":411,"caption":412,"w":124,"h":413},"\u002Fprojetos\u002Faether-parity.webp","Predicted vs. DFT parity for all four approaches on the same test set. This is the comparison the conclusion rests on.",656,[415,418,421],{"value":416,"label":417},"5,860","curated structures",{"value":419,"label":420},"0.9734","best ensemble R²",{"value":422,"label":423},"5 seeds","reproducible evaluation",[425],{"label":426,"href":427,"icon":428},"View code and research","https:\u002F\u002Fgithub.com\u002Fmauricioprb\u002Faether","ri:github-line",{},6,"Finding catalysts for the hydrogen evolution reaction through DFT calculations is expensive and slow. The practical question is whether a model pre-trained on millions of structures can replace that calculation within an acceptable error, and whether the advantage holds when the experiment is repeated across different seeds.","aether","projects\u002Fen\u002Faether","AI for screening green hydrogen catalysts.",[436,437,438,439,440,441,442],"Python","PyTorch","PyTorch Geometric","MACE","SchNet","SHAP","FastAPI","jrY0BAWPkcV4J0dJKTvc1S-Hgp1hb5ZpbF9fqhRo2qE",{"id":445,"title":446,"accessNote":105,"contribution":447,"cover":448,"coverAlt":449,"dataModel":450,"description":456,"extension":66,"facts":457,"gallery":464,"highlights":468,"links":478,"meta":482,"order":483,"problem":484,"requirements":485,"slug":501,"stem":502,"summary":503,"tags":504,"__hash__":511},"projects\u002Fprojects\u002Fen\u002Fcategoriza-brasil.yml","Categoriza Brasil","I built the platform as a modular Laravel monolith with six separate domains (public site, admin panel, identity, accounts, application clients and the institutional area). Its centerpiece is establishment registration wired to the Google Places API. Autocomplete search fills in the name, an address split into fields, coordinates, phone, website and a cover photo, and maps Google's categories onto the platform's health categories. Dragging the map marker triggers reverse geocoding. The first version of the interface used Vue with Pinia, and I migrated all of it to Livewire 4, which removed about 2,000 lines and left the application on a single stack. I also built the publications and media CMS with S3 storage, the public map with Leaflet clustering and the security layer, with CSP, rate limiting on login and sign-up, uploads validated by file content, email verification by PIN and a log of admin actions. In production, the app refuses to boot against a database without migrations and blocks commands that would wipe a non-local database.","\u002Fprojetos\u002Fcategoriza-home.webp","Categoriza Brasil home page showing the A, B and C health quality seals",{"src":451,"srcDark":452,"caption":453,"w":454,"h":455},"\u002Fprojetos\u002Fcategoriza-er.webp","\u002Fprojetos\u002Fcategoriza-er-dark.webp","Establishments, news, publications, pages and media record who created them, and the audit log stores the user's id and name without a foreign key, so the entry remains even if the account is deleted.",2296,1168,"An ecosystem for food-service health ratings, connecting public information, establishments and institutional management.",[458,460,462],{"label":112,"value":459},"Full stack development",{"label":115,"value":461},"Since 2023",{"label":118,"value":463},"Public platform",[465],{"src":466,"caption":467,"w":124,"h":125},"\u002Fprojetos\u002Fcategoriza-mapa.webp","The georeferenced map with clustering, filters by seal and location, and a list kept in sync with the viewport.",[469,472,475],{"value":470,"label":471},"6","domains in one monolith",{"value":473,"label":474},"1 search","fills in the establishment record",{"value":476,"label":477},"−2,000","lines from moving Vue to Livewire",[479],{"label":480,"href":481,"icon":148},"Visit platform","https:\u002F\u002Fcategorizabrasil.com.br",{},7,"Health ratings for bars, restaurants and bakeries needed to move off paper and become public, searchable information, without losing institutional control over who issues and maintains each seal.",[486,495],{"title":300,"items":487},[488,489,490,491,492,493,494],"Register establishments with an A, B or C seal, category, address, coordinates, contact, inspection date and cover photo.","Fill in the record from a Google Places search and adjust the position by dragging the map marker.","Show the public a map of published establishments, with marker clustering.","Publish news with galleries, publications and institutional pages from the admin panel.","Organize media in folders, with files on S3 storage.","Run a newsletter with one-click unsubscribe.","Create accounts with email verification by PIN, with admin-panel access granted by an administrator.",{"title":309,"items":496},[497,498,499,500],"Keep each domain in its own module inside a single monolith.","Apply CSP, rate limiting on login and sign-up, and upload validation by file content.","Log admin actions with user, action, target and IP.","Refuse to boot against an unmigrated database and block destructive commands outside the local environment.","categoriza-brasil","projects\u002Fen\u002Fcategoriza-brasil","Public food-safety ratings for restaurants and food services.",[505,506,507,43,508,509,45,510,44],"Laravel 12","Livewire 4","Alpine.js","Google Places API","Leaflet","S3","_GoOp1zead3dk0sPDBgBmVXq0QdJxxG81-dky3jN48Y",{"id":513,"title":514,"accessNote":105,"contribution":515,"cover":516,"coverAlt":517,"dataModel":105,"description":518,"extension":66,"facts":519,"gallery":525,"highlights":529,"links":538,"meta":541,"order":542,"problem":543,"requirements":105,"slug":544,"stem":545,"summary":546,"tags":547,"__hash__":548},"projects\u002Fprojects\u002Fen\u002Flabed.yml","LABED","I built the site from scratch in 2024 as a React SPA with Vite, with the lab's visual identity and records for members, projects and sponsors. In 2026 I migrated all of it to Nuxt 4 with Tailwind CSS v4, keeping the original identity. The migration replaced in-browser rendering with pre-rendered pages, and every project got its own address, with a photo gallery and sharing meta tags, which the SPA did not have. Members, projects and sponsors live in typed JSON files editable through Pages CMS, and the scroll animations, built with CSS and Lenis, respect the reduced-motion preference.","\u002Fprojetos\u002Flabed-home.webp","LABED website home page with the title Electronics and Development Lab","The website for UFN's Electronics and Development Lab, designed to make its projects, members and fields of work easier to discover.",[520,522,524],{"label":112,"value":521},"Design and development",{"label":115,"value":523},"2024 – 2026",{"label":118,"value":173},[526],{"src":527,"caption":528,"w":124,"h":125},"\u002Fprojetos\u002Flabed-projetos.webp","Every lab project gets its own page, pre-rendered and shareable.",[530,533,536],{"value":531,"label":532},"2024 → 2026","from a React SPA to pre-rendered Nuxt",{"value":534,"label":535},"A page per project","its own shareable address",{"value":212,"label":537},"members, projects and sponsors editable without code",[539],{"label":147,"href":540,"icon":148},"https:\u002F\u002Fwww.labed.com.br",{},8,"The lab was building combat robots, line followers and virtual reality booths, and none of it was findable outside Instagram. It needed a place where every project had its own address and could be shared.","labed","projects\u002Fen\u002Flabed","Website for UFN's Electronics and Development Lab.",[156,37,157,159,212],"Xz9M7x7KG-3ClgE4kK_5B1Vs4awQeOEy5SfBSoBCOAE","site\u002Fen","rVD0LKmiIsNXK-ZTWBPgk7qXY60OkNUs9pau3DvVHvs",1791995178856]