Menu
Back to Projects
InariSense

InariSense

Featured

A cross-platform gardening app that combines location-aware planting guidance, camera-based plant identification with explainable AI markers, weather-adjusted reminders, and an educational "why" behind every recommendation.

Primary Language
HTML
Last Updated
August 26, 2026

About This Project

InariSense is a cross-platform gardening app that goes beyond a static planting calendar. It combines location-aware planting guidance, camera-based plant identification, and weather-adjusted care reminders, with an explicit focus on explaining why a recommendation was made and how confident the app actually is in it. The backend is built with FastAPI and SQLAlchemy, using Alembic for versioned schema migrations, with a modular architecture organized by feature domain rather than by technical layer. External integrations (geocoding, USDA hardiness zone resolution, plant identification via the Pl@ntNet API) are built behind a provider-adapter pattern, so the underlying vendor can be swapped without touching business logic. The recommendation engine is deliberately rule-based and structured-data-first: every planting suggestion carries a confidence level and a note about its data source, and when real data isn't available (for example, there's no free, keyless API for frost dates), the app falls back to a clearly labeled estimate rather than presenting a guess as fact. The mobile app is built in Flutter with Riverpod for state management, backed by a custom design system (color tokens, typography scale, and a shared status/confidence visual language used consistently across every screen). A session bootstrap creates a persistent guest identity on first launch, so the app is usable immediately without a login flow. The project follows a disciplined GitFlow workflow with small, single-purpose pull requests, a CI pipeline that runs linting and automated tests (including a test that runs real database migrations, not just mocks) on every PR, and a Kanban board tracking every feature against the original product requirements and user journeys.

My Role & Contributions

Sole developer, end to end. Wrote the product requirements, personas, technical architecture, data model, and roadmap before writing any code. Designed and implemented the full backend (FastAPI, SQLAlchemy models, Alembic migrations, REST APIs) and the full Flutter mobile app (screens, state management, API integration, design system). Set up and maintained the GitFlow branching strategy, CI pipeline, and Jira project board. Integrated and verified three external APIs (geocoding, USDA zone data, plant identification) against their real endpoints, not just mocked interfaces.

Key Features

  • Location-based planting calendar with real geocoding and USDA hardiness zone resolution
  • Rule-based recommendation engine that shows confidence level and data source for every suggestion, never presenting a guess as fact
  • Full garden management — create and edit gardens, beds, containers, and plantings
  • Camera-based plant identification powered by the Pl@ntNet API, with top-candidate confidence scoring
  • Persistent guest sessions — no login required to start using the app
  • Custom design system with accessibility-conscious status indicators (color plus icon plus label, never color alone)
  • CI pipeline running automated linting and tests, including real database migration checks, on every pull request

Challenges & Solutions

No reliable free frost-date API. Every planting recommendation depends on knowing a location's frost dates, but no free, keyless API provides that data reliably. Rather than fabricate numbers from a formula, I built a fallback using general USDA zone-average estimates, explicitly labeled as low-confidence in the API response and the UI, with real location-specific data always preferred when available. This became a core design principle for the whole app: the system is honest about what it doesn't know. Cross-database migration compatibility. An Alembic auto-generated migration used a plain ALTER TABLE ADD CONSTRAINT to add a foreign key, which works on PostgreSQL but silently fails on SQLite, which doesn't support altering constraints that way. I caught this by actually running the migration against a local SQLite database rather than trusting the auto-generated output, and fixed it with Alembic's batch-mode operations, which use SQLite's copy-and-recreate strategy under the hood while remaining fully compatible with PostgreSQL. Debugging a third-party API integration blind. My development sandbox has no live internet access, so the Pl@ntNet plant-identification integration couldn't be tested end to end until it ran on a real device. The first real-device test failed with a low-level HTTP encoding error caused by mixing multipart file uploads with repeated form fields in a way the HTTP library didn't support. I diagnosed it by constructing a real HTTP request object locally to inspect the exact bytes being sent, identified the correct multipart encoding convention, and confirmed the fix on the next real-device run, which returned accurate species predictions with confidence scores.