Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 67 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,78 @@
# Plan-IT 🪐

A sprint planning and project management tool that uses **Google Calendar as its backend** — no server, no database. Projects, sprints, and work items are stored directly as Google Calendar events. Sign in with Google and your workspace lives in your own calendar.
A sprint planning and project management tool that uses **Google Calendar as its entire backend** — no server, no database, no infrastructure to maintain. Projects, sprints, and work items live as calendar events in your own Google account.

**[Try the live demo →](https://plan-it-ruby.vercel.app)** — no sign-in required.

---

## What makes this interesting

Most project management tools require a backend, a database, user accounts, and ongoing hosting costs. Plan-IT has none of that.

Every work item is a Google Calendar event. Every sprint is a multi-day event. Every project is a dedicated calendar. The app is a React SPA that talks directly to the Google Calendar REST API — your data stays in your Google account, and the whole thing deploys as a static site.

The AI Assistant takes this further: describe what you want in plain English and Claude uses tool-calling to autonomously create, update, move, and delete items across projects — including creating new projects mid-session and immediately populating them.

---

## Features

### Core views
- **Board** — kanban-style drag-and-drop across New → Active → Resolved → Closed columns
- **Backlog** — flat list with sprint filter, sortable by any column
- **Sprints** — progress bars, per-sprint item lists, and one-click item creation
- **Calendar** — month/week view of sprints and deadlines

### Project management
- **Projects** — each project is a dedicated Google Calendar; drag to reorder in the sidebar
- **Sprints** — multi-day events with status tracking (Planned / Active / Completed)
- **Work items** — tasks, bugs, and features with type, priority, assignee, deadline, and Fibonacci story points (1 2 3 5 8 13 21)

### Global + Create menu
Click **+ Create** from any page to open a dropdown and add:
- Work Item
- Sprint (with project picker)
- Project
- ✨ AI Planner

### AI sprint & project planning
Powered by **Claude (claude-haiku)**:
- **AI Planner** — describe what you want to build, set sprint count and team size, and Claude generates a full multi-sprint project plan with tasks, priorities, and story points. Preview all sprints before committing.
- **Generate Sprint with AI** — on the Sprints tab, generate a single sprint from a goal description.
### Board, Backlog, Sprints, Calendar
- Kanban board with drag-and-drop (optimistic updates — no flicker)
- Board sorting by date, priority, or story points — persists across refreshes
- Backlog table with sprint filter and deadline column; overdue items highlighted
- Sprint progress bars, per-sprint item lists, one-click item creation
- Month/week calendar view of sprints and deadlines

### Projects
- Each project is a dedicated Google Calendar
- Drag to reorder in the sidebar
- Full create/delete support

### Work items
- Types: Task, Bug, Feature
- Statuses: Planned → Active → Resolved
- Priority, assignee, deadline, Fibonacci story points (1 2 3 5 8 13 21)

### ✨ AI Assistant
Powered by **Claude** with native tool use:
- Describe what you want in plain text — Claude decides what to create, update, or delete
- Operates across all projects simultaneously
- Can create new projects and immediately populate them
- Chains operations mid-session (create a sprint, then assign items to its real ID)
- Supports: `create_project`, `create_sprint`, `update_sprint`, `delete_sprint`, `create_work_item`, `update_work_item`, `delete_work_item`, `move_work_item`
- Live action log shows each operation as it executes

### Demo mode
Click **Try Demo** on the login screen to explore the full app without a Google account. Pre-seeded with realistic projects, sprints, and work items. Data resets on refresh — nothing is stored anywhere.
Full app experience without a Google account. Pre-seeded with realistic projects, sprints, and work items. Resets on refresh.

---

## Architecture decisions

### Why Google Calendar as the backend?
The Calendar API gives you authenticated CRUD, a globally distributed data store, and offline sync for free — without writing a single line of server code. Each Plan-IT concept maps cleanly to a Calendar primitive:

| Concept | Stored as |
|---|---|
| Project | Google Calendar (`description` prefixed `[Plan-IT][pos:N]`) |
| Sprint | Multi-day calendar event (`planitType: "sprint"`) |
| Work item | Calendar event (`planitType: "workitem"`) |

Work item fields (type, status, priority, story points, assignee, sprint) are stored in `extendedProperties.private` on each event.

### Why no database?
Adding a database means: schema design, migrations, backups, a server to host it, auth between the server and DB, and ongoing costs. Google Calendar handles all of that. The tradeoff is a slightly unusual data model — but for a project management tool where you're already asking users to authenticate with Google, it's a natural fit.

### Authentication & persistence
- Google OAuth2 — your data stays in your own Google Calendar, nothing goes to a third-party server
- Login persists across page refreshes (token cached in `localStorage`, auto-expires with the OAuth token)
### Why browser-side API calls?
There's no backend to proxy through, so the app calls the Calendar API and Anthropic API directly from the browser. This is explicitly supported by both (`dangerouslyAllowBrowser: true` in the Anthropic SDK). For a personal or portfolio deployment this is the right call — it keeps the architecture dead simple. A production multi-tenant version would proxy AI calls through a server.

### Why React + TypeScript over a framework?
The app has complex drag-and-drop state, optimistic updates, and multi-step dialogs that would fight against a server-rendering model. Vite + React keeps the build fast and the client state management straightforward.

### Why Fibonacci story points?
Industry standard in agile estimation. The gaps between values (1, 2, 3, 5, 8, 13, 21) force estimators to make a decision rather than splitting the difference — a 4-point estimate usually means you haven't thought it through.

---

Expand All @@ -49,7 +85,7 @@ Click **Try Demo** on the login screen to explore the full app without a Google
| Drag and drop | `@dnd-kit/core`, `@dnd-kit/sortable` |
| Auth | `@react-oauth/google` |
| Backend | Google Calendar REST API (direct fetch, no SDK) |
| AI | Anthropic SDK (`@anthropic-ai/sdk`) — browser-side |
| AI | Anthropic SDK (`@anthropic-ai/sdk`) — Claude with tool use |

---

Expand All @@ -62,7 +98,7 @@ Click **Try Demo** on the login screen to explore the full app without a Google
3. Enable the **Google Calendar API** under APIs & Services → Library
4. Go to APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID
5. Application type: **Web application**
6. Add `http://localhost:5173` to Authorized JavaScript Origins (add your production domain too)
6. Add `http://localhost:5173` to Authorized JavaScript Origins
7. Copy the generated **Client ID**

### 2. Configure environment variables
Expand All @@ -75,12 +111,10 @@ cp .env.example .env
# Required
VITE_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com

# Optional — enables AI sprint/project planning
# Optional — enables AI Assistant
VITE_ANTHROPIC_API_KEY=sk-ant-...
```

> **Note:** The Anthropic key is used client-side. For a personal or portfolio app this is acceptable; for a shared deployment, proxy the API calls through a server.

### 3. Install and run

```bash
Expand All @@ -92,18 +126,6 @@ Open [http://localhost:5173](http://localhost:5173), sign in with Google, or cli

---

## How data is stored

Plan-IT has no database. Everything lives in your Google Calendar:

| Concept | Stored as |
|---|---|
| Project | A Google Calendar (description prefixed `[Plan-IT][pos:N]`) |
| Sprint | A multi-day calendar event (`planitType = "sprint"`) |
| Work item | A calendar event (`planitType = "workitem"`) |

Work item fields (type, status, priority, story points, assignee, sprint association) are stored in the event's `extendedProperties.private` map. Project display order is encoded in each calendar's description as `[pos:N]` and updated when you drag to reorder.

## Permissions

The app requests `https://www.googleapis.com/auth/calendar` scope to read and write calendar data for the signed-in user. No data is sent to any server other than Google's Calendar API (and Anthropic's API if you enable AI features).
The app requests `https://www.googleapis.com/auth/calendar` scope to read and write calendar data for the signed-in user. No data is sent to any server other than Google's Calendar API (and Anthropic's API if AI features are enabled).
Loading