Skip to content
Dylan San GabrielDylan
API reference
Contact

GET /api/work

Work

Everything here I built at RMH3 Dental Supply, where I'm the only engineer.

The internal ERP that runs a dental supply company

Live · 2026 · sole engineer · 13 daily users

The company sold on six websites using six different tools that never agreed. I built the one system that runs it all, about 500 orders a day.One system for orders, inventory, repricing, shipping, service and books across six sales channels, built from scratch, about 500 orders a day.

Read the project

The ERP's warehouse map: a floor plan of the main building with its storage areas named and their numbered locations, a building switcher, a bin search and a count of 415 items not yet on a shelf. Rooms that aren't storage are left unlabeled, and two zones named for suppliers read "Vendor zone".

Running a dozen AI coding sessions on one repo

Live · 2026 · sole engineer

I use AI helpers to write much of the code, like a chef running a fast kitchen. This is the system of rules and checks that keeps the plates right.How I use AI coding agents at scale without vibe-coding, auto-loading rules, hooks that block the dangerous operations, and proof before calling it done.

Read the project

GET/api/work

Request

curl "https://dylansg.com/api/work"
source: src/content/projects/*

Response200 OK · 2.0 KB

{
  "count": 2,
  "items": [
    {
      "id": "internal-erp",
      "title": "The internal ERP that runs a dental supply company",
      "status": "live",
      "year": 2026,
      "category": "work",
      "role": "sole engineer · 13 daily users",
      "summary": "One system for orders, inventory, repricing, shipping, service and books across six sales channels, built from scratch, about 500 orders a day.",
      "summary_plain": "The company sold on six websites using six different tools that never agreed. I built the one system that runs it all, about 500 orders a day.",
      "stack": [
        "TypeScript",
        "Node.js",
        "Express",
        "React",
        "PostgreSQL",
        "Railway",
        "GitHub Actions",
        "Docker"
      ],
      "metrics": {
        "orders_day": "~520",
        "products": "32K",
        "sales_channels": "6",
        "daily_users": "13",
        "orders_ingested": "300K+",
        "price_changes_logged": "138K+",
        "automated_tests": "2,721",
        "scheduled_jobs": "180"
      },
      "page": "https://dylansg.com/work/internal-erp"
    },
    {
      "id": "agent-fleet",
      "title": "Running a dozen AI coding sessions on one repo",
      "status": "live",
      "year": 2026,
      "category": "work",
      "role": "sole engineer",
      "summary": "How I use AI coding agents at scale without vibe-coding, auto-loading rules, hooks that block the dangerous operations, and proof before calling it done.",
      "summary_plain": "I use AI helpers to write much of the code, like a chef running a fast kitchen. This is the system of rules and checks that keeps the plates right.",
      "stack": [
        "Claude Code",
        "Node.js",
        "Git hooks",
        "GitHub Actions",
        "Jest",
        "Markdown"
      ],
      "metrics": {
        "commits_in_6_months": "14K",
        "parallel_sessions": "10+",
        "operating_docs": "300+"
      },
      "page": "https://dylansg.com/work/agent-fleet"
    }
  ],
  "page": "https://dylansg.com/work"
}

Live: this is the answer from this site’s API, not a mock. Send re-runs the request with your parameters; if the answer names a page, it opens.

The ERP

6 parts, each written up on its own.

  • Repricing every minute without a race to the bottom

    Prices used to be a spreadsheet someone updated every morning. Now a robot checks every product once a minute, and knows better than to start a price war.Replaced a morning pricing spreadsheet with an engine that reprices every minute, with cooldowns, floors, and a rule to never chase the lowest price.

  • Six channels, one product master

    Six websites, each with its own version of the truth about our 32,000 products. One catalog, owned by people, that none of them is allowed to overwrite.Order intake and listing sync for six channels, with the identity rules that keep 49,000 marketplace listings from ever overwriting the product catalog.

  • Counting what sells, not what exists

    A nightly job decides which products are worth counting and reordering. It had been calling nearly everything important, which is the same as calling nothing important.A nightly classifier ranked all 27,215 products and made 1,979 of them class A. Ranking only what sells turned a fake Pareto into a real one.

  • Printing labels when the printer can lie about it

    Every box needs a label and a slip, printed on machines in a warehouse nobody logs into. This is what prints them, checks they came out, and repairs itself when an update goes bad.A thermal-label pipeline and a self-updating Windows print fleet — predicted widths, verified feeds, and an update that rolls itself back.

  • Keeping the books and the app in agreement

    The sales system and the accounting books have to agree to the penny. This is the connection that keeps them agreeing, and the logbook that ended the false alarms.A two-way QuickBooks Desktop integration over the Web Connector, plus a claims ledger so a finance discrepancy is refuted once, not rediscovered monthly.

  • The toolbox, extracted

    The system itself must stay private, but the useful parts don't have to. Nine pieces pulled out and scrubbed clean — real warehouse code, public and readable.Nine self-contained pieces of the ERP, lifted out and sanitized — barcode parsing, thermal-print layout, a self-updating device agent, invoice parsers.

GET/api/work/{id}

Parameters

Request

curl "https://dylansg.com/api/work/internal-erp?fields=subsystems"
source: src/content/projects/{id}

Response200 OK · 2.1 KB · Open /work/internal-erp

{
  "subsystems": [
    {
      "id": "internal-erp/repricing",
      "title": "Repricing every minute without a race to the bottom",
      "summary": "Replaced a morning pricing spreadsheet with an engine that reprices every minute, with cooldowns, floors, and a rule to never chase the lowest price.",
      "page": "https://dylansg.com/work/internal-erp/repricing"
    },
    {
      "id": "internal-erp/channel-sync",
      "title": "Six channels, one product master",
      "summary": "Order intake and listing sync for six channels, with the identity rules that keep 49,000 marketplace listings from ever overwriting the product catalog.",
      "page": "https://dylansg.com/work/internal-erp/channel-sync"
    },
    {
      "id": "internal-erp/inventory",
      "title": "Counting what sells, not what exists",
      "summary": "A nightly classifier ranked all 27,215 products and made 1,979 of them class A. Ranking only what sells turned a fake Pareto into a real one.",
      "page": "https://dylansg.com/work/internal-erp/inventory"
    },
    {
      "id": "internal-erp/printing",
      "title": "Printing labels when the printer can lie about it",
      "summary": "A thermal-label pipeline and a self-updating Windows print fleet — predicted widths, verified feeds, and an update that rolls itself back.",
      "page": "https://dylansg.com/work/internal-erp/printing"
    },
    {
      "id": "internal-erp/quickbooks",
      "title": "Keeping the books and the app in agreement",
      "summary": "A two-way QuickBooks Desktop integration over the Web Connector, plus a claims ledger so a finance discrepancy is refuted once, not rediscovered monthly.",
      "page": "https://dylansg.com/work/internal-erp/quickbooks"
    },
    {
      "id": "internal-erp/toolbox",
      "title": "The toolbox, extracted",
      "summary": "Nine self-contained pieces of the ERP, lifted out and sanitized — barcode parsing, thermal-print layout, a self-updating device agent, invoice parsers.",
      "page": "https://dylansg.com/work/internal-erp/toolbox"
    }
  ],
  "page": "https://dylansg.com/work/internal-erp"
}

Live: this is the answer from this site’s API, not a mock. Send re-runs the request with your parameters; if the answer names a page, it opens.

AI coding sessions

2 parts, each written up on its own.

  • One task per session, a dozen at a time

    How a normal day goes. Each AI helper gets one job, one list on the side of my screen shows which ones need me, and every split-up job ends with a check that all of it came back.The daily loop behind the fleet, one task per session, background sessions watched from one side panel, and a merge-back check that closes every run.

  • The guardrails, extracted

    The safety system I describe in the fleet write-up, pulled out on its own and stripped of everything company-specific — the actual traffic-cop code, cleaned up and published.The session-lock layer, fleet scripts, context tooling and review-agent configs behind the fleet write-up, lifted out of the private repo and sanitized.

GET/api/work/{id}

Parameters

Request

curl "https://dylansg.com/api/work/agent-fleet?fields=subsystems"
source: src/content/projects/{id}

Response200 OK · 751 B · Open /work/agent-fleet

{
  "subsystems": [
    {
      "id": "agent-fleet/daily-workflow",
      "title": "One task per session, a dozen at a time",
      "summary": "The daily loop behind the fleet, one task per session, background sessions watched from one side panel, and a merge-back check that closes every run.",
      "page": "https://dylansg.com/work/agent-fleet/daily-workflow"
    },
    {
      "id": "agent-fleet/tooling",
      "title": "The guardrails, extracted",
      "summary": "The session-lock layer, fleet scripts, context tooling and review-agent configs behind the fleet write-up, lifted out of the private repo and sanitized.",
      "page": "https://dylansg.com/work/agent-fleet/tooling"
    }
  ],
  "page": "https://dylansg.com/work/agent-fleet"
}

Live: this is the answer from this site’s API, not a mock. Send re-runs the request with your parameters; if the answer names a page, it opens.