Skip to main content
Back to projects 01 · TerraCore | Smart Farming Live

TerraCore | Smart Farming

The TerraCore | Smart Farming ecosystem, the farm-management platform for Colombian farms. It brings together the app that also works without a signal, the presentation page, and the official product documentation.

TerraCore dashboard: real-time metrics, production charts, and livestock distribution
Problem
Colombian farms track animals, crops, and accounts across notebooks, spreadsheets, and WhatsApp, and the systems that exist are too complex.
Solution
One platform to manage animals, crops, production, health, and finances, which also works without a signal.
Result
In validation with real clients in Colombia. Working product in production.
01

App

Multi-user, offline-first PWA: Django backend and React frontend.
View detailsHide
  • Django
  • DRF
  • PostgreSQL
  • Celery
  • Redis
  • JWT
  • React
  • TypeScript
  • Dexie
  • Tailwind CSS
01

The problem

Agricultural producers in Colombia had no software designed for them: existing ERPs were too complex, and an Excel sheet with login was not enough to manage livestock, animal health, and production simultaneously. Operations were scattered across notebooks, spreadsheets, and WhatsApp groups.

No traceability

When was that animal vaccinated? Nobody knows for certain.

Invisible stock

The feed runs out and nobody saw it coming.

No signal, no data

There is no internet in the paddock. The record is left for later, and later never comes.

Disconnected data

The notebook says it was vaccinated, but not how much supply it used or what it cost.

02

Results

  • Working product in production.
  • Being validated with real clients in Antioquia, Colombia.
View technical details OpenHide technical details
03

What I built

  1. 01

    Backend in Django and DRF on PostgreSQL. Celery with Redis runs the scheduled tasks (billing and alerts). Authentication with short-lived, rotating tokens.

  2. 02

    Strict data isolation between companies: every query is limited to the requester's company before it answers.

  3. 03

    Business logic in services with transactions and row locking. Every endpoint validates role, plan, and facility, and errors follow a uniform contract.

  4. 04

    Frontend in React, TypeScript, Vite, and Tailwind, with one folder and one state hook per module.

  5. 05

    Installable PWA on Android and iOS without app stores. The Service Worker caches the app and reads; data lives in a local database (IndexedDB with Dexie) and every write enters an outbox queue.

  6. 06

    A single sync for ten models: push in dependency order, paginated pull, and a version per record. The server answers accepted, conflict, or rejected with a reason, and revalidates like the REST API.

  7. 07

    Offline beyond records: a queue of deferred actions (inviting users, changing roles) and saved reads so every screen opens without network. Only card payment needs a connection.

  8. 08

    CSV import for onboarding and CSV export with administrator approval.

  9. 09

    Security: restricted-access API documentation and periodic security reviews of the critical functions.

  10. 10

    Containerized infrastructure with an isolated test environment and a review step before production. Vulnerability scanning and reproducible deployment on every release. Over 1,000 automated tests in each repository.

Dashboard

Metrics computed on the device: expired and upcoming vaccines, low stock, and pending activity.

Livestock

Unique code, health status, facility, and a detail view with vaccination history.

Crops

Type, status, area, and planting date, with search and filters.

Supplies

Stock, minimum, unit cost, and a movement history with its reason.

Tools

Equipment, purchase cost, and maintenance.

Production

Batches with supplies used, sale price, and margin.

Animal health

Vaccines with the supply applied, cost, and booster date.

Finance

Summary, history, profitability per batch, suppliers, purchases, and losses, depending on the plan.

Facilities and permissions

Each user sees only the facilities that apply to them.

Users and roles

Administrator, Operator, and Collaborator (read-only, depending on the plan), with invitations and plan limits.

Subscription

Plan, payment, history, and cancellation.

Activity

Notifications per module and a sync rejections tray.

You log a vaccine and this happens on its own

  1. 01 Vaccine applied to an animal, with supply, quantity, cost, and booster date.
  2. 02 The supply is deducted in the same transaction. If there is no stock, the record is not created either.
  3. 03 The Supplies history gets a "Vaccine logged" movement.
  4. 04 The animal's detail view shows the vaccine in its history.
  5. 05 The Dashboard counts expired or soon-to-expire vaccines (30 days).
  6. 06 The treatment cost adds to the health expense of the period P&L.
  7. 07 If stock drops below the minimum, the team is alerted.
  8. 08 If the record is deleted, the supply returns to stock.

You log a production batch

  1. 01 Each supply used is deducted, validating stock grouped per supply (all or nothing).
  2. 02 The batch leaves a "Production logged" movement.
  3. 03 The batch cost (quantity times unit cost) is computed against its revenue (quantity times sale price).
  4. 04 If the cost exceeds revenue, the administrator is alerted.
  5. 05 The revenue enters the period P&L.

You change the active facility

  1. 01 Every screen is scoped to that facility.
  2. 02 A scope badge shows whether you are seeing one facility or all.
  3. 03 A vaccine inherits its animal's facility.

All of this without signal

  1. 01 The same flow is saved on the device.
  2. 02 When the network returns it is applied on the server with the same rules: stock, roles, plan, and facility.
04

Design

  1. 01

    The product starts from its own design in Claude Design, with a clickable prototype (View design button).

  2. 02

    Deep green as the primary color and amber as the accent over warm neutrals. Inter for text and Poppins for headings.

  3. 03

    Atomic design with CSS tokens shared with the landing: atoms, molecules, and layout organisms.

  4. 04

    Responsive navigation: a side panel from 1024 px and a bottom bar with a More sheet on mobile. Both come from the same source and a test fails if they drift apart.

  5. 05

    Offline state is always visible: banner, pending counter, a Pending mark on every row, and a rejections tray.

  6. 06

    With an active facility, a scope badge always says whether the screen shows that facility or all of them.

  7. 07

    Forms built for Colombia: phone with dial code and SVG flags, and CC or CE identity document. Spanish URLs and a guided tour on first use.

05

Architecture decisions

01 Offline-first with PWA ViewClose
Context
In pens and paddocks the signal is intermittent or nonexistent, and the record is left for later.
Trade-off
A traditional web app fails without network. A native app requires stores and double maintenance.
Installable PWA with a local IndexedDB database (Dexie). Every write goes to a queue and syncs when the network returns. The Service Worker caches the app and reads.
02 Integrated modules with server-side rules ViewClose
Context
A field action touches several records: vaccine, supply, animal, and cost.
Trade-off
Isolated modules are simple, but force you to log the same thing several times. Connecting them forces you to decide who owns each piece of data.
Logic lives in services with transactions and row locking. The animal owns the facility of its vaccines and modules import in one direction only.
03 Multi-user with roles and facilities ViewClose
Context
A farm is run by a team of 2 to 10 people with different duties, in one or several facilities.
Trade-off
A single role exposes everything. Too many roles become unmanageable.
Three roles, per-facility permissions, user and facility limits per plan, and invitations with a temporary password.
04 Strict multitenancy ViewClose
Context
Several companies share one instance and one company's data must never reach another.
Trade-off
Separate instances isolate better but multiply operations and cost.
Isolation per company is resolved on the server and never depends on data the client sends. Every query is limited to the company before it answers.
05 Sync without overwriting data ViewClose
Context
Two devices can edit the same record or move the same stock while offline.
Trade-off
Last write wins is simple but loses data. Resolving conflicts requires versioning and more code.
Every record carries a version and the server answers accepted, conflict, or rejected with a reason. Offline stock travels as a difference, not an absolute value.
06 Data portability ViewClose
Context
Producers distrust platforms that retain their data or make exit difficult.
Trade-off
Unchecked export makes leaks easier. Blocking exit destroys trust.
CSV import and export available, and export goes through administrator approval.
06

Learnings

01

Defining data isolation between companies early avoids rewrites: it shapes every modeling decision.

02

Sync cannot skip validations: it was fixed to validate like the REST API (roles, plan, and facility).

03

Connecting modules forces you to decide who owns each piece of data: a vaccine's facility is its animal's facility.

07

Roadmap

Now

  • Product in production, in validation with real clients in Colombia.

Next

  • Remove the old vaccination subsystem.
  • Bring the Finance history down to the facility level.

Later

  • Labor and fixed and variable costs (currently zero).
  • Custom reports, an integrations API, and a DIAN and NIIF base.

Out of scope for the MVP

  • Financial forecasting, full electronic invoicing, multi-currency, and automatic PDF reports.
02

Landing

Astro conversion landing with plans and a diagnostic form.
View detailsHide
  • Astro
  • TypeScript
  • Tailwind CSS
  • Vercel Functions
  • Supabase
  • Brevo
  • Playwright
  • GA4
  • SEO
  • A11y
01

The problem

A SaaS platform without a conversion landing loses traffic before the producer reaches the app. It has to explain what changes compared to Excel, notebooks, and WhatsApp, show the product, say what each plan includes, and offer a simple way to ask for a demo.

Unclear plans

If what each plan includes is not visible, the producer hesitates before starting. Limits and scope have to be in plain sight.

What sets it apart is invisible

That the modules talk to each other is not obvious. Without demonstrating it before the plans, the landing loses the conversion.

Distrust around data

The producer does not want their costs and production data leaving the farm. Without an explicit privacy section, trust is never earned.

Little signal in the field

If the product works without internet, the landing has to say so from the first screen and without fine print.

02

Results

  • Landing in production, with the diagnostic form storing requests and notifying by email.
  • Three plans published with clear limits per plan, and visible cancellation terms.
View technical details OpenHide technical details
03

What I built

  1. 01

    Astro with static output, no adapter and no UI framework: the JavaScript is vanilla, one script per component. Deployed on Vercel.

  2. 02

    Atomic design with an import alias per layer (atoms, molecules, organisms, and template). Color, type, and spacing tokens live in a single CSS file and Tailwind extends them. Inter, Poppins, and JetBrains Mono are self-hosted, with no third-party font requests.

  3. 03

    Conversion funnel in 13 sections: Hero, Impact, trust strip, Modules, Product, Benefits, Security, Plans, FAQ, and closing. Metrics, case studies, and testimonials are built but hidden until real data exists.

  4. 04

    Each section's data is typed TypeScript in a single file (plans, impact, benefits, and FAQ). The FAQ feeds both the visible accordion and the FAQPage JSON-LD from the same source.

  5. 05

    Three plans: Seed (1 facility, 5 users), Professional (up to 5 facilities, 10 users), and Enterprise (unlimited facilities and users). Each plan button opens the form with the operation size already selected. What is sold matches what the backend enforces: facility and user caps, the Collaborator role, Tools and CSV export from Professional, and losses in Finance only on Enterprise.

  6. 06

    Diagnostic form that sends JSON to a server function. It validates and normalizes the data, saves the lead in Supabase, and notifies by email through Brevo. A repeated email creates no new row and the notification never blocks the save.

  7. 07

    Spam protection without a captcha, with checks on the client and on the server. It only saves in production.

  8. 08

    Analytics: optional GA4, with events on every CTA (Hero, plans, WhatsApp, and form), plus Vercel Web Analytics and Speed Insights. A floating WhatsApp button on every page.

  9. 09

    Technical SEO: title, description, canonical, Open Graph and Twitter, sitemap, robots.txt, and llms.txt. JSON-LD with Organization, WebSite, SoftwareApplication with its offers, and FAQPage.

  10. 10

    Security through headers: a restrictive CSP and anti-framing and permissions headers.

  11. 11

    Quality: Vitest for logic, Playwright for the flow (landing, form, plans, FAQ, and mobile menu), and Lighthouse on every PR with accessibility as a blocking threshold. A test ties the landing's limits to what the product actually does.

Hero with promise and demo

'Replace Excel and WhatsApp' headline, a works-without-internet chip, a button to the diagnostic, and a demo video in a lightbox.

Modules framed around the pain point

Livestock, supplies, tools (from the Professional plan), production, and animal health, each in a bento that starts from the problem it solves and not from the feature.

Cascade integration

Visual flow: vaccine applied, supply deducted, and an expiry date with an alert. And minimum stock, alert to the administrator. It is what the product does and it shows what sets it apart before the plans.

Real product screenshots

Tabs for Dashboard, Livestock, Supplies, Production, and Animal Health with app screenshots, automatic rotation, and a pause button.

Privacy and security

Five commitments: encryption in transit, roles and permissions, CSV export with administrator approval, no data mining, and nightly backup.

Plans and form

Three plans in a carousel with limits and scope, frequently asked questions, and a free diagnostic form with WhatsApp as an alternative.

04

Design

  1. 01

    The design starts from a clickable prototype, reachable from the View design button.

  2. 02

    Deep green as the primary color and amber as the accent over warm neutrals, in the same visual family as the PWA.

  3. 03

    Poppins for headlines, Inter for text, and JetBrains Mono for figures and details. All three are self-hosted.

  4. 04

    Numbered sections with an editorial eyebrow and a rhythm that alternates light and dark backgrounds to separate each funnel step.

  5. 05

    Modules in a bento with product mini-views (tables and metric cards) instead of generic illustrations.

  6. 06

    Real screenshots in tabs with automatic rotation and pause, and plans in a carousel with arrows and pause.

  7. 07

    Hamburger menu below 1000 px, a floating WhatsApp button, and a skip link on every page.

05

Architecture decisions

01 Copy focused on the pain, not the product ViewClose
Context
The agricultural producer does not search for 'agri-industrial SaaS'. They search to stop using Excel, notebooks, and WhatsApp groups.
Trade-off
Technical copy does not connect with the field. Pain-focused copy does, but requires knowing the real operation.
Hero with no mention of the stack: 'Replace Excel and WhatsApp in your farm operation' and 'It is not about earning more, it is about losing less'. A before and after table reinforces the contrast.
02 Integration before the plans ViewClose
Context
TerraCore's difference from Excel is that the modules talk to each other. That is not obvious to the producer.
Trade-off
Going straight to the plans before demonstrating differential value lowers conversion.
The integration block ('One action. The whole system up to date.') sits inside Modules, before the plans section. The user understands the value before seeing the plans.
03 Trust before the plans ViewClose
Context
Production and cost data are sensitive to the producer, and distrust blocks the purchase.
Trade-off
Omitting privacy assumes a trust that in agriculture must be earned explicitly. Placing it before the plans makes the page longer.
The security section sits right before Plans, with concrete commitments: no data mining or AI training and CSV export with administrator approval.
04 A single funnel to the form ViewClose
Context
Three plans with three destinations scatter the leads and make it hard to know what each visitor asked for.
Trade-off
A single destination loses direct plan purchase. In return, every request arrives complete and with context.
The three plan buttons lead to the same form and preselect the plan's operation size. First a 30-minute diagnostic and, if it fits, a 14-day trial with no card.
05 GA4 to iterate with real data ViewClose
Context
Without behavioral metrics, landing design is intuition: you do not know which sections are read or which button converts.
Trade-off
GA4 adds a third-party script with privacy implications, and it has to be declared and able to be turned off.
GA4 is only active when configured and records events on every CTA (Hero, plans, WhatsApp, and form). The privacy policy declares it together with Vercel Web Analytics.
06 Static, with a single server function ViewClose
Context
A landing does not need its own backend, but the form has to store leads without exposing keys.
Trade-off
A serverless function does not run under Astro's dev server, and the test environment has no database.
The site is static and the form talks to a server function that stores the data in Supabase. Outside production it validates and does not save.
07 No invented social proof ViewClose
Context
A landing for a product under validation is tempted to fill in placeholder metrics, cases, and testimonials.
Trade-off
Those sections add trust, but with fake data they take it away. Leaving them out today costs conversion.
The three sections are built and hidden until real data exists. In addition, an automated test compares the landing's limits with what the product does.
06

Learnings

01

A landing for a non-technical niche must speak the client's language: every section was written in farm vocabulary, not software vocabulary.

02

Separating the value demonstration from the plans section lowers the barrier: the producer arrives at the plans having already understood what differentiates TerraCore from Excel.

03

It is cheaper to keep a social proof section hidden until real data exists than to remove invented figures later.

07

Roadmap

Now

  • Landing in production capturing diagnostic requests.

Next

  • Activate metrics, case studies, and testimonials once real data exists.
03

Documentation

Official product documentation: usage, features, getting started, and support.
View detailsHide
  • Astro
  • MDX
  • TypeScript
  • Lucide
  • Vitest
  • Playwright
  • Vercel
01

The problem

The guide is for the end customer: an owner, administrator, or operator of a farm in Colombia, who is not technical. They need to learn the product without depending on a support call: how to start, what each module does, what to do when something does not go as expected, and who to contact.

View technical details OpenHide technical details
02

What I built

  1. 01

    Astro with static output, no React and no adapter, deployed on Vercel. JavaScript is vanilla TypeScript: search, side-menu state, and the table of contents.

  2. 02

    Content in MDX with Astro content collections: one page per file, with a title, summary, and icon typed by the collection schema. 34 pages in 8 groups: Getting started, Your team, Your farm, Your numbers, Data and connection, Your subscription, App flows, and Reference.

  3. 03

    A single source of truth for navigation: the list of groups and pages defines the side menu, the mobile navigation sheet, the home page, and the previous and next pager, in reading order. A test fails if a listed page has no file, or the reverse.

  4. 04

    Its own writing blocks, available on every page without importing them: notices, numbered steps, fields, screenshots, cards, badges, and tables.

  5. 05

    Atomic design with an import alias per layer (atoms, molecules, organisms, templates, and layouts), with the TerraCore design system components recreated in Astro.

  6. 06

    Client-side search: the index is generated at build time as a static JSON file and the browser queries it, with no server and no third-party service. It ignores accents and letter case.

  7. 07

    Navigation in grouped menus that remember whether they are open, a table of contents per page, and a pager between pages. Each page shows the date of its last review against the product, taken from a single constant.

  8. 08

    Technical SEO: a generated sitemap, robots.txt, a manifest, and the es-CO language declared in the document.

  9. 09

    Security through headers, with a restrictive CSP with no third-party origins and anti-framing, anti-sniffing, referrer, and permissions headers.

  10. 10

    Quality: ESLint, Prettier, and type checking with astro check, unit tests with Vitest, and end-to-end tests with Playwright (the guide and the mobile navigation), with CI on every PR.

03

Design

  1. 01

    Color, spacing, radius, and shadow tokens are a faithful copy of the TerraCore design system's: they are not invented or redefined on the site.

  2. 02

    Lucide icons with a uniform stroke, through a single component.

  3. 03

    Text in Colombian Spanish, in the informal register, with long dates and es-CO number formats, and no emojis.

  4. 04

    A side bar on desktop; on mobile, a top bar with a bottom sheet to navigate.

One click away

Less work by hand, more customers who find you.

I build landing pages, websites, automations, chatbots and custom apps, plus the content that gets you found. Security by design and a fixed price.

MVP in 6 to 10 weeks. Limited availability, I reply within 24 hours.