1. Projects
  2. Internal Dashboard

An all-in-one Internal Dashboard, concept to production in under two weeks.

As Director of Business Operations at Doodle Pirates Foundation, I designed one role-based platform for the whole team and shipped it fast by directing Cursor cloud agents and reviewing every change.

Org
Doodle Pirates Foundation
Role
Director of Business Operations
Stack
React + Vite, Hono, Cloudflare Worker, Airtable
My Work page: a strip of today’s meetings with Join buttons, a “Check today’s shop work” card with Verify, Correct and Reject, and the start of Today’s focus with a week meter.
<2 wksConcept to production
152Reviewed pull requests
1,218Automated tests
$1,000+Software savings per employee per year, by my estimate

The savings figure is my estimate, per employee per year. It is not audited.

The problem

The team was disconnected: projects and tasks lived in different places, so nobody could see who was doing what. As a nonprofit startup we couldn’t afford a stack of subscriptions, and we employ neurodivergent people, so everyone learns and works differently. I designed one affordable, easy-to-use system with one place to see what to focus on.

What it does

One role-based platform replacing a stack of separate tools. By my estimate, it avoids $1,000+ per employee in annual software costs.

  • Project & task management
  • Daily focus
  • Onboarding (intern and volunteer tracks)
  • PTO
  • Documentation
  • Shift scheduling
  • Time clocking
  • Hours export for payroll (beta)
  • Manufacturing shop-floor kiosk
Your open tasks, grouped by project: Giving Tuesday, Ops Portal launch and Winter grant cycle, each row with status, business line, estimated hours, due date and a Done button.

Plan: milestones and a live timeline

Each department gets a Gantt-style timeline of its projects and milestones, with counts for what’s open, next and blocked. Dependency lines show what waits on what. Hover for details, or click to edit the record in Airtable.

Operations Milestones & Projects: counts for open projects, open milestones, next milestone and blocked, above a timeline of projects and milestones with a Today line.

Ask Otis

Ask Otis is a Claude-powered assistant built into the dashboard. Ask it to add or update a task, project or milestone and it returns an editable card. Nothing changes until the person presses Approve; the server rechecks permissions before saving.

Adding a task, on a phone

From meetings to daily focus

The dashboard doesn’t read meeting notes. Action items reach the task list from people and from AI assistants we run outside it. Every weekday at 6:30 AM it picks each person’s daily focus, with a rule-based fallback if the AI is down.

Today’s focus card for Friday: “Write the Task Manager walkthrough for the team”, due today, with a one-line reason and Done, Continue tomorrow and Skip today buttons. A week meter above shows 2 of 5 done.

How data flows

Everyone signs in with a work Google account, and every write passes a permission check before reaching Airtable, the source of truth. Docs are real Google Docs, calendar sync is one way, and Ask Otis only suggests.

Illustration · not a screenshotRequests & writesReads coming backAsk Otis, gated by a person
How data flows through the Internal DashboardA team member signs in with a work Google account through Cloudflare Access. Requests go from the Dashboard to the API, which runs on the same Cloudflare Worker. The API checks permissions, then reads and writes Airtable and saves docs to Google Docs. Shifts, PTO and sick days are pushed one way to Google Calendar; nothing comes back from the calendar. Ask Otis suggestions go to a person, and only what that person approves is written to Airtable. A text version follows the diagram.How data flows through the Internal DashboardA team member signs in with a work Google account through Cloudflare Access. Requests go from the Dashboard to the API, which runs on the same Cloudflare Worker. The API checks permissions, then reads and writes Airtable and saves docs to Google Docs. Shifts, PTO and sick days are pushed one way to Google Calendar; nothing comes back from the calendar. Ask Otis suggestions go to a person, and only what that person approves is written to Airtable. A text version follows the diagram.
Text version of the diagram
  1. Team member (browser, phone or shop-floor kiosk) → Cloudflare Access. Sign-in with a work Google account, before anything else loads.
  2. Cloudflare Access → Dashboard (React + Vite). Signed-in requests. Each person’s Employee Level decides what they can see and do.
  3. Dashboard → API (Hono, on the same Cloudflare Worker). Requests such as a task, a shift or a PTO day.
  4. API → Airtable (source of truth). Reads, and writes after a permission check on the server.
  5. API → Google Docs. Documentation pages, which are real Google Docs. The live editor saves a few seconds after typing stops.
  6. API → Google Calendar (one way). Shifts, PTO and sick days, pushed after a schedule save, a “Resync this week” press or a shop job assignment. Out-of-office days and holidays stay off the calendar, and nothing is read back.
  7. Ask Otis (Claude-powered assistant) → A person, for approval. Editable cards: a new task, a task update, or a project or milestone update.
  8. Approve → API, then Airtable. Only what the person approved is written, after another permission check on the server.
  9. Separately, each person’s own Google Calendar → My Work. Today’s meetings, read-only and private to that person. This is not part of the schedule sync and isn’t drawn above.

A day in the dashboard

From meeting action items to a confirmed week

  1. 01

    Action items land in the task list

    Meeting action items become tasks in Airtable.

    Your open tasks, grouped by project: Giving Tuesday, Ops Portal launch and Winter grant cycle, each row with status, business line, estimated hours, due date and a Done button.
  2. 02

    Focus is picked at 6:30 AM

    Three to five open tasks per person, each with a short reason.

    Today’s focus card for Friday: “Write the Task Manager walkthrough for the team”, due today, with a one-line reason and Done, Continue tomorrow and Skip today buttons. A week meter above shows 2 of 5 done.
  3. 03

    Work the list

    Each person marks a focus card Done, Continue tomorrow or Skip today. Done also closes the task.

    My Work page: a strip of today’s meetings with Join buttons, a “Check today’s shop work” card with Verify, Correct and Reject, and the start of Today’s focus with a week meter.
  4. 04

    Ask Otis, then Approve

    Ask Otis turns a request into an editable card, saved only after Approve.

    The Ask Otis panel beside the Task Manager, showing an editable “Update task” card with title, due date, status, project and milestone fields. A task name is blurred.
  5. 05

    Clock in on the shop floor

    Staff scan a badge, enter a PIN, clock in at a station and work through the task’s steps, tapping “I need help” if stuck.

    Kiosk screen for a woodworking station: a large 9:41 AM clock, “On the clock”, and a task card “Sew 10 pieces of fabric” with a four-step checklist and I finished it, I need help and Not today buttons.
  6. 06

    Check the schedule, add PTO

    PTO saves right away and appears as a read-only event on the person’s Google Calendar.

    Work Schedule week of Oct 26: blue 9 to 5:30 shifts Monday to Wednesday, and PTO tags on Thursday and Friday with those shifts shown in red.
  7. 07

    Confirm the week

    Each person confirms their hours or asks for a correction, and their manager approves the week.

    Shop payroll, Weekly sign-off: a table of people with their week, where one person shows “Confirmed by worker” with an Approve week button and the rest show “Not confirmed yet”.

See it in motion

Sample-data screen recordings

Opening the dayClock in, then meetings, focus and tasks.
Kiosk clock-inBadge, PIN, clock in, checklist.

How it was built

I set the requirements, structure and approval rules, and AI agents did the typing. I reviewed every change: 152 pull requests, backed by 1,218 automated tests.

App
React + Vite front end and a Hono API, on one Cloudflare Worker
Sign-in
Cloudflare Access with work Google accounts, gated by Employee Level
Source of truth
Airtable, with a server permission check on every write
Docs
Real Google Docs in a shared Drive, edited live by several people
Caching
Cloudflare KV, edge cache and Durable Objects, inside the free tier
Built with
Claude Code, Claude Design, Cursor cloud agents directed through Grok Bot
Documentation page “How we apply for a grant”, labelled as a Google Doc with an Open in Google Docs link, a formatting toolbar and the page text.
Documentation
Welcome aboard page: “7 / 23 done” progress, the About you section with contact info, emergency contact and shirt size marked Done, and side panels for team onboarding, your people and key dates.
Onboarding

Screens

Phone view of the daily focus card with the week meter, the task, its reason and the Done, Continue tomorrow and Skip today buttons.
Daily focus on a phone
Kiosk screen for a woodworking station: a large 9:41 AM clock, “On the clock”, and a task card “Sew 10 pieces of fabric” with a four-step checklist and I finished it, I need help and Not today buttons.
Shop-floor kiosk
Phone view of an Ask Otis “New task” card: “Order more sanding pads for the wood shop”, with assignee, due date, status and department fields.
Ask Otis on a phone
Documentation page “How we apply for a grant”, labelled as a Google Doc with an Open in Google Docs link, a formatting toolbar and the page text.
Documentation
Welcome aboard page: “7 / 23 done” progress, the About you section with contact info, emergency contact and shirt size marked Done, and side panels for team onboarding, your people and key dates.
Onboarding
After approval: a green notice says Otis saved the task update, and the panel reads “Saved 1 of 1.” A task name is blurred.
Ask Otis, approved

All names, tasks and numbers are invented sample data, and one vendor name is blurred. The dashboard and its code are private to Doodle Pirates Foundation.

What broke & how I fixed it

  1. Autosave could wipe a real document

    The collaborative editor could save an empty page over a real Google Doc. I added guards that refuse empty or near-empty saves.

  2. Saving one department erased the others

    Updating one department’s intern access deleted every other department’s permissions. Deletes are now scoped to the department being edited.

  3. Airtable quirks caused silent failures

    Linked-record filters returned nothing and attachment uploads appended instead of replacing, so “Mark done” looked successful but didn’t stick. I fixed both and added tests.

  4. A duplicate constant stopped deploys

    Two features merged the same day defined the same constant, which broke the build and paused deploys until I fixed it.

What I’d do differently

  1. Build write-safety rules and contract tests against live data from day one, not sample data that hides real-world quirks.

  2. Require a passing build before anything merges.

  3. Ship fewer modules first and get the core task flows adopted before adding more.