Avatar

Case Study

Ourvio

A lightweight platform for shared accountability — built for groups, not solo grinders.

Role Independent Developer
Timeline 2025 – Present
Stack React · TypeScript · Django · PostgreSQL
Live site ourvio.com ↗

Most task apps assume you're working alone. But many real responsibilities are shared — families coordinating chores, roommates dividing errands, small teams keeping track of who owns what.

Ourvio is a lightweight system designed specifically for groups that want shared accountability without the overhead of enterprise project management tools. I built it end-to-end, from product concept to deployment.

The Problem

Most task apps are optimized for one person. That's not a criticism — it's a deliberate design choice. Personal productivity is a huge space, and tools like Things, Todoist, and Notion do it well. But a significant slice of real-world responsibilities doesn't look like a solo to-do list.

Think about the actual texture of shared life: families splitting household tasks, roommates managing shared errands, a three-person startup trying to stay in sync without standing up a new Jira instance, a friend group planning a trip. For all of these, the same frustrating choice exists: use a personal task app with no real concept of a group, or spin up a full project management suite that feels like overkill the moment you invite someone.

The gap between "my private to-do list" and "enterprise project management" is real — and surprisingly underserved. There's a whole category of lightweight, shared accountability that neither end of the market handles well.

That's the problem Ourvio is trying to solve.

The Idea

The core insight was simple: what if tasks were group-first by default? Not personal tasks you can optionally share, but tasks that live in a group context from the start.

In Ourvio, every task belongs to a group. Everyone in the group has visibility into what's open, what's in progress, and what's done. Completion is visible — not just to you, but to the people who care. Accountability isn't a feature you configure later; it's the default behavior.

A lightweight system for shared accountability, built for the way people actually collaborate in small, real-world contexts. Not a solo productivity tool. Not a heavy PM suite. Something in between.

What Ourvio Does

At its core, Ourvio organizes work around groups rather than individuals. Each group shares a simple workspace where members can:

  • Create and assign tasks to group members
  • Track progress and mark tasks complete
  • Comment and collaborate on individual tasks
  • Attach files and supporting context
  • Export task data when needed

The goal is to make shared responsibility visible — without introducing the complexity of full project management systems.

Ourvio dashboard

Product Design

The biggest product design challenge was restraint.

It's tempting, when building a task management product, to keep adding capability. Labels, priorities, swimlanes, automations, integrations. Every feature has a use case. But I kept coming back to the core question: who is this actually for?

The target user is someone who needs shared visibility on a modest set of tasks — not someone managing a 50-person engineering sprint. Adding complexity to serve the second audience would actively hurt the first. So I made explicit decisions to stay lightweight:

  • Tasks live in groups. The group is the primary organizing unit, not the project or the board.
  • Shared visibility is the default. There are no private tasks. If you're in the group, you see the full picture.
  • Simple interaction model. Create a task, assign it, complete it. That's most of what people actually need.
  • No roadmaps, sprints, or velocity charts. Ourvio is not Jira-lite. It's intentionally narrower — which makes it faster and less intimidating to actually use.

Getting the task creation flow to feel immediate — no friction, no modals stacked on modals — turned out to be more nuanced than I expected. The goal was that adding a task should feel as quick as sending a text message.

Building the MVP

I started with the smallest version of the core loop: create a group, invite a member, create a task, complete it. Everything else was out of scope until that loop felt good.

From there I expanded incrementally: task assignment, status tracking, member permissions, profile and auth. I kept a running list of "nice to haves" that I intentionally deferred. Getting the loop right mattered more than covering every edge case on day one.

One area that took more time than expected: file attachments. Adding files to tasks sounds simple, but it touches a lot of surfaces — storage, validation, size limits, MIME type checks, access control, preview rendering. I used Supabase Storage with server-side validation to keep attachments secure and size-constrained, making sure files were only accessible to members of the relevant group.

Technical Architecture

The stack prioritizes reliability and maintainability.

Frontend React + TypeScript for a type-safe UI and scalable component architecture.
Backend Django + Django REST Framework powering the API, authentication, and permission model.
Database & Storage PostgreSQL via Supabase with Supabase Storage for attachments. Access control lives in the Django layer — not raw Supabase RLS — keeping authorization consolidated and testable.
Infrastructure Fly.io Docker deployment with automated builds and predictable scaling, avoiding unnecessary operational complexity.

A key architectural principle: authorization lives entirely in the API layer, not the frontend, ensuring consistent and auditable access control.

Key Engineering Challenges

Group membership access control

Every request that touches a task, group, or member goes through a permission check that validates group membership. I wrote a reusable view mixin so this check couldn't be accidentally omitted on new endpoints.

Secure task visibility

Tasks are scoped to groups at the query level — not just filtered post-fetch. If you're not in the group, the task doesn't exist from your perspective. Horizontal privilege escalation is prevented by design, not convention.

Optimistic UI updates

Task state changes — completing, reassigning — update the UI immediately without waiting for the server response. If the API call fails, the state rolls back. This makes the app feel fast even across real-world latency.

Pagination and list scaling

Task lists use cursor-based pagination to keep performance consistent as groups grow. The frontend handles loading additional pages without blowing away the existing loaded state.

CSV export

Group admins can export task data as a CSV. The export is generated server-side from a filtered queryset — no intermediary file is written to disk. Fast, stateless, and straightforward to audit.

Rate limiting and security hardening

Auth endpoints are rate-limited at the API layer. Password reset and account creation flows have explicit throttles to reduce abuse risk. Security headers — HSTS, X-Frame-Options, CSRF protection — are enforced in production.

File upload validation

Uploads are validated on both client and server: size limits, allowed MIME types, and extension checks. Files are stored under a path scoped to the group, with no public URLs — downloads go through an authenticated endpoint.

Tradeoffs & Decisions

Not everything made the cut, and that was intentional.

I deliberately deferred multi-assignee tasks. The UX complexity of multiple assignees — how do you display them, who is "responsible," how do notifications work — wasn't worth solving before the core loop was validated. One assignee keeps the accountability model clean.

I also skipped real-time updates in v1. For most use cases, page-load or a manual refresh is perfectly fine. WebSockets add operational complexity and are expensive to implement correctly. I'd revisit once there's clear evidence that latency is a real blocker for actual users.

Billing and paid plans are designed for but not yet shipped. The role and permission infrastructure supports paid tiers — I just haven't opened that flow. Launching free first was the right call for building early traction without friction.

Every deferred decision was a tradeoff I tracked explicitly, not something I forgot. The goal was always to ship something usable fast, learn from real use, and expand thoughtfully.

Outcome & Reflection

Ourvio is live and in use. More importantly, it's a product I genuinely use myself.

Building it end-to-end — from data model to React component to deployed container — gave me clarity about where the hard parts of full-stack product development actually live. It's not the technology. It's the accumulation of small decisions: what to show when a list is empty, how to handle a failed upload gracefully, whether a permission check should live in a view or a model method.

Getting those details right requires caring about the product, not just the code. Ourvio showed me I can hold both. I care whether the task creation flow feels fast and whether the CSV export handles encoding edge cases.

The project also reinforced something I think matters in engineering: willingness to constrain scope in service of quality. A smaller, polished, well-secured product beats a sprawling one that half-works.

Where It Goes Next

The roadmap is clear, even if the timing is deliberate:

  • Multi-assignee tasks — the most-requested feature, and with the core model stable it's the right next step
  • Richer notifications — email digests, completion alerts, @mentions in task comments
  • Billing and paid plans — the infrastructure is ready; it needs a payment flow
  • Deeper admin controls — group-level visibility settings, member role customization, audit logs
  • A native mobile experience — the current app is responsive, but a purpose-built mobile interface would unlock a new category of use cases

Ourvio isn't done. But it's real, it works, and it solves a genuine problem. That's the foundation worth building on.