Files
ProjectE/README.md
T
bot-hermes a60b75f075 feat: full plan execution - CI/CD, critical fixes, UX polish, secondary/advanced features, E2E + docs
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.
2026-08-10 08:53:18 +00:00

226 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (00000005)
├── 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.