Skip to content
Hi! I am Gab

All experience

Freelance

Full-stack developer

Amry Pharmacy logo

Amry Pharmacy

Dates
Jun 2026 – Sep 2026
Location
Davao del Norte
Technologies
Chat GPT, Claude, Django, Django REST, Linux, Neon, Next.js, PostgreSQL, Python, React, Render, Typescript, Vercel

Full-stack developer responsible in building the web-based inventory and sales management system.

Responsibilities

  • Gathered requirements with the owner and wrote the PRD, TRD and architecture docs.
  • Designed, built and tested the Django REST API and the Next.js Storefront and Back Office apps.
  • Deployed and maintained staging and production on Vercel and Render.
  • Shipped every change, including hotfixes, through feature branches and pull requests, even as the only developer.

What I contributed

  • Built the inventory ledger as the single write path for all 5 stock flows (receiving, sales, transfers, stock counts, disposals), tracking batches across 4 location states with zero negative-stock writes allowed.
  • Designed the backend as 10 Django apps with a service layer, covered by 5 to 10 unit tests per module.
  • Tied every sale to an open cashier shift, with first-expiry-first-out batch picking and Rx, DSWD and Senior/PWD rules enforced at checkout.
  • Shipped 2 installable PWAs from one Next.js codebase, Storefront for tablets and phones and Back Office for desktop, serving 3 branches.
  • Added capability-based access that controls both what a user can do and which of the 2 apps they can open.
  • Built automatic SKU numbering with room for 999,999 items, plus a duplicate-name check that catches the same item entered twice with different casing.
  • Added push notifications for 4 event types: low stock, expiring batches, approvals and incoming deliveries.
  • Migrated 3,053 products and 41 opening stock batches from local data into production.
  • TReplaced a recurring Loyverse cost of $900 to $1,080 a year with a one-time build.

Challenges

  • Phones couldn't stay logged in. iOS Safari dropped the session cookie because the API was on a different domain. I routed every API call through a same-origin Next.js proxy. Live testing then caught a trailing-slash bug that broke login, which the build alone had missed.
  • First production deploy. It failed in stages: build config, static files, allowed hosts, a hidden 500 error, cross-site cookies, build-time environment variables, and a CSRF origin off by one slash. Adding server-side logging turned the hidden 500 into a one-line answer: a typo in the database name.
  • Moving data between databases. Stock batches failed on foreign keys, and branch IDs differed between local and production. I remapped branches by their stable codes instead of numeric IDs.
  • A blocked checkout. Senior/PWD sales stalled with an HTTP 415 error, because the prescription endpoint accepted file uploads but not JSON.
  • Implementing barcodes correctly on the dataflow of the inventory ledger, making sure it is correct and consistent from inventory-in to inventory-out.
  • As the sole developer, meeting deadlines and learning new technologies such as PWA notifcation and pywebpush, enable me to get out of my comfort zone.

Outcome

The system is live at all three branches. It was delivered for a one-time payment, replacing a Loyverse setup that would cost $900 to $1,080 a year. Ensure, better, smooth, and fast inventory tracking which benefits overall operational efficiency.

Lessons learned

  • Debug from evidence. Make the system show the real error through logs before guessing. One log line beat five theories.
  • Browser security is part of the backend. CORS, SameSite cookies and CSRF are three separate gates, and "works on localhost" hides all of them.
  • Concurrency and data integrity. Atomic transactions, row locking against race conditions, and idempotency keys generated on the client so a retried sale is never recorded twice.
  • Safe API design. Expose only the endpoints a model should have. A route that doesn't exist can't be misused, even by an admin.
  • Environment parity. One codebase serves dev, staging and production through environment variables. Frontend public variables are baked in at build time, and hosted Postgres needs TLS and connection health checks.
  • Portable data. Numeric IDs don't survive a move between databases, but stable business keys do.
  • Maintainable structure. A service layer for business rules, separate read and write hooks on the frontend, and explicit imports that prevent circular dependencies.

Case study

  • Amry Pharmacy - Sales and Inventory Management System

    Built the sales and inventory system for Amry Pharmacy, a three-branch retail pharmacy in Davao del Norte (Asuncion, Kapalong, Talaingod). It replaces Loyverse and a stack of Excel sheets and paper logs with one Django REST API on PostgreSQL and two installable PWAs: a Storefront for counter work

    See Case Study : Amry Pharmacy - Sales and Inventory Management System