Phase 0 (CI/CD): fix root typecheck to cover api+worker+web; reconcile migration story into idempotent db:migrate (db:sync + db:triggers); add Gitea Actions quality/deploy/smoke workflow; rewrite README/AGENTS/DEPLOY docs; add requireWorkspaceAccess + recordActivityForEntity conventions. Phase 1 (critical fixes): calendar delete + drag/resize DnD; canvas card CRUD + bulk save + debounced autosave; logout route; graph edge workspaceId derivation; real analytics endpoints (drop Math.random); task board droppable columns + reorder persistence; Tiptap notes editor with sanitized HTML rendering; remove insecure passkey auth; domain/owner scoping (IDOR) on all by-ID routes + search/ export/realtime scoping; command palette routing + agent mention fetch; agent activity SSE handler; graph fly-to with tracked positions. Phase 2 (UX polish): login on design system; Sonner toasts app-wide; shared Loading/Empty/Error state components; working density/sidebarPos/reduce-motion settings; Inter typography; consolidated status-colors lib; unified detail routes; dashboard sort/realtime/responsive fixes; mobile responsive; a11y (radiogroups, sanitized snippets, badge labels). Phase 3 (features): daily notes timezone fix + delete + autosave + mood/energy create; active-domain store + topbar picker; graph domain picker + navigable entity links; tag assign/remove UI + server-side tag filter; real CSV export + import validation; custom fields on tasks. Phase 4 (advanced): migrate job worker into apps/worker (webhook delivery with HMAC, recurring spawn, ai_dispatch disabled); webhook queue helper + entity event enqueuing + test endpoint fix; recurring scheduledJobs pipeline; agents CRUD + permission editing + activity filters; real notifications feed; MCP polish (validation, error codes, domain scoping, dead sql leftover). Phase 5 (E2E + docs): rewrite Playwright suite for the Vite SPA (15 specs, new auth helpers, chromium-only in CI); add ephemeral-Postgres e2e CI job; rewrite docs/API.md for the real Hono API.
226 lines
11 KiB
Markdown
226 lines
11 KiB
Markdown
# Project E
|
||
|
||
A personal project, habit, and task tracker built for the AI-agent era. Track tasks and habits, manage projects, write notes, and let AI agents read and write your data through a built-in MCP (Model Context Protocol) server.
|
||
|
||
## Features
|
||
|
||
- **Tasks:** Kanban boards, priorities, due dates, subtasks, time tracking, recurring tasks, dependencies, and attachments
|
||
- **Habits:** Daily/weekly/custom frequencies, streak tracking, mood logging, skip days, and completion scoring
|
||
- **Projects:** Organize work by domain, track progress through milestones, set deadlines, and manage team members
|
||
- **Notes:** Rich text editor with wikilinks, note graph visualization, and bookmarks
|
||
- **Reports:** Weekly, monthly, project, and habit reports with templates
|
||
- **Milestones:** Plan project phases, set dependencies, and track completion
|
||
- **Domains & Tags:** Organize everything across life domains (work, personal, health) with flexible tagging
|
||
- **AI Agents:** Register agents with API keys, assign permission tiers, and dispatch work via @mentions
|
||
- **Webhooks:** Subscribe to events, deliver payloads with HMAC signatures, and track delivery history
|
||
- **Analytics:** Task completion rates, habit consistency, time summaries, and streak tracking
|
||
- **Realtime:** SSE feed backed by PostgreSQL LISTEN/NOTIFY keeps the UI in sync across devices
|
||
- **Background Worker:** Bun process for webhook deliveries, agent mentions, recurring tasks, and data cleanup
|
||
- **MCP Server:** 18 tools for AI agents to read and write data through the Model Context Protocol
|
||
|
||
## Architecture
|
||
|
||
```
|
||
┌───────────────────────────────────────────────────────────────┐
|
||
│ Frontend (Vite SPA) │
|
||
│ React 19 · TanStack Router/Query · shadcn/ui · Tailwind │
|
||
└──────────────────────────┬────────────────────────────────────┘
|
||
│ REST API + SSE
|
||
│ (Vite dev proxy → :3001)
|
||
┌──────────────────────────▼────────────────────────────────────┐
|
||
│ API (Hono on Bun, apps/api) │
|
||
│ Auth (JWT) · Routes · Realtime SSE · MCP server · Webhooks │
|
||
└──────────────────────────┬────────────────────────────────────┘
|
||
│ Drizzle ORM (postgres driver)
|
||
┌──────────────────────────▼────────────────────────────────────┐
|
||
│ PostgreSQL 16 + Drizzle ORM │
|
||
│ Schema in packages/db/src/schema.ts · migrations in drizzle/ │
|
||
└────────────────────────────────────────────────────────────────┘
|
||
|
||
┌────────────────────────────────────────────────────────────────┐
|
||
│ Background Worker (Bun, apps/worker) │
|
||
│ Webhook delivery · Agent mentions · Recurring tasks · │
|
||
│ Data cleanup │
|
||
└────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Tech Stack
|
||
|
||
| Layer | Technology |
|
||
|-------|-----------|
|
||
| Frontend | Vite 5, React 19, TypeScript 5.9 |
|
||
| Routing / Data | TanStack Router, TanStack Query, TanStack Table |
|
||
| UI Components | shadcn/ui, Radix UI, Lucide icons |
|
||
| Styling | Tailwind CSS 3.4, tailwind-merge, class-variance-authority |
|
||
| State Management | Zustand 5 |
|
||
| Rich Text | Tiptap 3 |
|
||
| Forms | React Hook Form, Zod 4 validation |
|
||
| Calendar | react-big-calendar, date-fns |
|
||
| Charts | Recharts 3 |
|
||
| Graph Visualization | react-force-graph-2d |
|
||
| Drag & Drop | @dnd-kit |
|
||
| Backend | Hono 4 on Bun 1.3 (`apps/api`) |
|
||
| Database | PostgreSQL 16 with Drizzle ORM and the `postgres` driver |
|
||
| Authentication | JWT (jose) in an httpOnly session cookie; API keys for agents |
|
||
| Background Jobs | Bun worker (`apps/worker`) |
|
||
| MCP Server | JSON-RPC over HTTP at `/api/mcp`, served by the API |
|
||
| Monorepo | Turborepo 2.5, Bun workspaces |
|
||
| Testing | Playwright (E2E in `e2e/`) |
|
||
|
||
## Prerequisites
|
||
|
||
- **Bun** 1.3.14 or later (the repo pins `bun@1.3.14`)
|
||
- **PostgreSQL** 16 (local install, or the Docker container from the compose file)
|
||
- **Docker + Docker Compose** for the production stack (see [DEPLOY.md](DEPLOY.md))
|
||
|
||
## Quick Start
|
||
|
||
1. **Clone the repository**
|
||
|
||
```bash
|
||
git clone https://git.buzzbee.dev/Vibing/ProjectE.git
|
||
cd ProjectE
|
||
```
|
||
|
||
2. **Install dependencies**
|
||
|
||
```bash
|
||
bun install
|
||
```
|
||
|
||
3. **Start PostgreSQL**
|
||
|
||
```bash
|
||
docker compose up -d db
|
||
```
|
||
|
||
Or point `DATABASE_URL` at an existing PostgreSQL 16 instance.
|
||
|
||
4. **Set environment variables**
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
Fill in `DATABASE_URL`, `POSTGRES_PASSWORD`, `AUTH_SECRET`, `INITIAL_ADMIN_EMAIL`, and `INITIAL_ADMIN_PASSWORD`.
|
||
|
||
5. **Apply the database schema**
|
||
|
||
```bash
|
||
bun run db:migrate
|
||
```
|
||
|
||
Pushes the schema (`drizzle-kit push --force`) and applies the search-vector triggers. Idempotent, safe to re-run.
|
||
|
||
6. **Start the development servers**
|
||
|
||
```bash
|
||
bun run dev
|
||
```
|
||
|
||
- API (Hono) on `http://localhost:3001`
|
||
- Web (Vite) on `http://localhost:3000`, proxying `/api` and `/mcp` to :3001
|
||
|
||
7. **Sign in as the initial admin**
|
||
|
||
Open `http://localhost:3000` and sign in with `INITIAL_ADMIN_EMAIL` and `INITIAL_ADMIN_PASSWORD`. The first login creates the admin account.
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
project-e/
|
||
├── apps/
|
||
│ ├── api/ # Hono + Bun API server (routes, middleware, auth)
|
||
│ ├── web/ # Vite + React 19 SPA (TanStack Router, shadcn/ui)
|
||
│ ├── worker/ # Bun background worker (src/index.ts)
|
||
│ └── web-legacy/ # Old Next.js app, kept for reference only
|
||
├── packages/
|
||
│ ├── db/ # Drizzle schema, client, and ORM access
|
||
│ └── shared/ # Shared types, schemas, and constants
|
||
├── drizzle/ # Drizzle migrations (0000–0005)
|
||
├── script/ # deploy.sh, apply-triggers.ts
|
||
├── e2e/ # Playwright E2E tests
|
||
├── .gitea/workflows/ # Gitea Actions CI/CD (ci.yml)
|
||
├── docker-compose.yml # Production stack (db, api, spa, worker)
|
||
├── Caddyfile # SPA serving + /api reverse proxy
|
||
├── Dockerfile.api # API image
|
||
├── Dockerfile.spa # SPA build + Caddy image
|
||
├── Dockerfile.worker # Worker image
|
||
├── bunfig.toml
|
||
├── drizzle.config.ts
|
||
└── package.json
|
||
```
|
||
|
||
## Available Scripts
|
||
|
||
| Command | Description |
|
||
|---------|-------------|
|
||
| `bun run dev` | Run the API (watch) and the Vite dev server concurrently |
|
||
| `bun run dev:api` | API server with watch on :3001 |
|
||
| `bun run dev:web` | Vite dev server on :3000 |
|
||
| `bun run build` | Production build of the web SPA (`vite build`) |
|
||
| `bun run typecheck` | `tsc --noEmit` across api, worker, and web |
|
||
| `bun run db:push` | Push schema changes to the database (`drizzle-kit push`) |
|
||
| `bun run db:sync` | Push schema with `--force` (idempotent) |
|
||
| `bun run db:generate` | Generate a new Drizzle migration from schema changes |
|
||
| `bun run db:triggers` | Apply the search-vector triggers (idempotent) |
|
||
| `bun run db:migrate` | `db:sync` + `db:triggers`; what deploys run |
|
||
| `bun run db:studio` | Open Drizzle Studio |
|
||
| `bun run deploy` | Run `script/deploy.sh` (see DEPLOY.md) |
|
||
|
||
## Environment Variables
|
||
|
||
Variables live in a root `.env` file (not `.env.local`). Copy from `.env.example`.
|
||
|
||
| Variable | Description | Default |
|
||
|----------|-------------|---------|
|
||
| `DATABASE_URL` | PostgreSQL connection string | (required) |
|
||
| `POSTGRES_PASSWORD` | Password for the `project_e` user (used by docker-compose) | (required) |
|
||
| `AUTH_SECRET` | Secret that signs JWT sessions (`NEXTAUTH_SECRET` is accepted as a fallback) | (required) |
|
||
| `INITIAL_ADMIN_EMAIL` | Email for the account created on first sign-in | (required) |
|
||
| `INITIAL_ADMIN_PASSWORD` | Password for the account created on first sign-in | (required) |
|
||
| `NODE_ENV` | `development` or `production` | `development` |
|
||
| `PUBLIC_URL` | Absolute URL used for emails and webhooks | `http://localhost:3000` |
|
||
| `COOKIE_SECURE` | Set `true` behind HTTPS | `false` |
|
||
| `ALLOWED_HOSTS` | Comma-separated list of allowed hostnames | `localhost` |
|
||
|
||
## Testing
|
||
|
||
Playwright E2E tests live in `e2e/` (config at the repo root). Start the dev stack (`bun run dev`) in one terminal, then run:
|
||
|
||
```bash
|
||
# Full suite
|
||
bunx playwright test
|
||
|
||
# Interactive UI mode
|
||
bunx playwright test --ui
|
||
|
||
# Plain list reporter
|
||
bunx playwright test --reporter=list
|
||
```
|
||
|
||
Tests run against Chromium, Firefox, WebKit, Mobile Chrome, and Mobile Safari, and cover authentication, tasks, habits, projects, notes, reports, analytics, calendar, dashboard, search, settings, webhooks, realtime, MCP, and import/export.
|
||
|
||
## Deployment
|
||
|
||
Production runs as a docker-compose stack (db, api, spa, worker) on the host. Gitea Actions drives deploys: a `quality` gate runs on every push and PR, a `deploy` job on pushes to `main` runs `script/deploy.sh`, and a `smoke` job verifies health afterwards. Manual steps, rollback, and troubleshooting are in [DEPLOY.md](DEPLOY.md).
|
||
|
||
## Documentation
|
||
|
||
- [API Documentation](docs/API.md): REST API endpoints, authentication, error handling
|
||
- [MCP Server Documentation](docs/MCP.md): Model Context Protocol tools and usage
|
||
- [Deployment Guide](docs/DEPLOYMENT.md): Production deployment, SSL, backups, monitoring
|
||
- [Development Guide](docs/DEVELOPMENT.md): Contributing, code structure, testing strategy
|
||
- [Architecture Documentation](docs/ARCHITECTURE.md): System design, data flow, security
|
||
|
||
## Contributing
|
||
|
||
1. Fork the repository on Gitea and create a feature branch
|
||
2. Make your changes
|
||
3. Run `bun run typecheck` and `cd apps/web && bun run build` before committing
|
||
4. Push the branch and open a pull request. CI runs the same quality gate on every push and PR.
|
||
|
||
## License
|
||
|
||
This project is private and proprietary.
|