createEvent.mutateAsync({ start: slot.start, end: slot.end })}
+ onEventClick={(event) => navigate(`/events/${event.id}`)}
+/>
+```
+
+**Effort:** L · **Impact:** 🟡 Medium
+
+---
+
+### 31. `@ottabase/testimonials` — Social Proof Collection & Display
+
+**Description:** Request testimonials via email, collect via a public form, moderate in admin, and display with
+`` and `` components. Integrates with the page builder.
+
+**Why:** Social proof is the fastest trust signal. Manually collecting and displaying testimonials is tedious. A
+self-hosted tool avoids per-seat pricing on tools like Testimonial.to.
+
+**Sample implementation:**
+
+```typescript
+export class Testimonial extends BaseModel {
+ static entity = 'testimonials';
+
+ static async requestViaEmail(customerEmail: string, appId: string) {
+ const token = crypto.randomUUID();
+ await TestimonialRequest.create({ customerEmail, appId, token });
+ await sendEmail({ to: customerEmail, template: 'testimonial-request', data: { token } });
+ }
+}
+```
+
+```tsx
+
+```
+
+**Effort:** S · **Impact:** 🟡 Medium
+
+---
+
+### 32. `@ottabase/announcements` — In-App Announcement Banners
+
+**Description:** Admin-created announcements shown as dismissible banners or modals to users. Targeting by plan,
+role, or feature flag. Seen-state tracked per user in D1. Supports rich content via `@ottabase/ottarenderer`.
+
+**Why:** Communicating new features, upcoming maintenance, or plan changes without a full notification system is a
+common need. A lightweight in-app announcement system is faster than push notifications for most use cases.
+
+**Sample implementation:**
+
+```tsx
+// Wrap your app layout once
+
+ {children}
+
+
+// Auto-renders unseen announcements at the top of every page
+```
+
+```typescript
+// Create announcement from admin
+await Announcement.create({
+ title: 'New AI features are here!',
+ body: editorJsContent,
+ target: { plans: ['pro', 'enterprise'] },
+ startsAt: Date.now(),
+ endsAt: Date.now() + 7 * 86400_000,
+});
+```
+
+**Effort:** S · **Impact:** 🟡 Medium
+
+---
+
+### 33. `@ottabase/ottamap` — Maps Component
+
+**Description:** Lightweight map component wrapping Leaflet (open-source, free tiles) with MarkerCluster, GeoJSON
+overlay, and click handlers. Optional Mapbox adapter for premium tiles.
+
+**Why:** Location features appear in local services, event apps, and analytics dashboards. Leaflet on its own requires
+styling and clustering boilerplate; a thin wrapper eliminates the recurring setup.
+
+**Sample implementation:**
+
+```tsx
+import { OttaMap, Marker, MarkerCluster } from '@ottabase/ottamap';
+
+
+
+ {locations.map((loc) => (
+ setSelected(loc)} />
+ ))}
+
+
+```
+
+**Effort:** S · **Impact:** 🟢 Nice-to-have
+
+---
+
+### 34. `@ottabase/devtools` — Browser DevTools Panel
+
+**Description:** Browser extension (Chrome/Firefox) that shows OttaORM query log, active RLS context, RBAC
+permissions, feature flags, and cache stats for the current page. Zero production overhead — panel only active in dev.
+
+**Why:** Debugging OttaORM, RLS, and RBAC in a browser context currently requires console.log hunting. A dedicated
+DevTools panel cuts debugging time significantly, especially for new contributors.
+
+**Sample implementation:**
+
+```typescript
+// packages/devtools/src/panel.ts
+// Injected only in dev mode via @ottabase/config ENVIRONMENT check
+
+window.__OTTABASE_DEVTOOLS__ = {
+ queries: queryLog,
+ context: currentRLSContext,
+ flags: resolvedFlags,
+ permissions: currentPermissions,
+};
+```
+
+```typescript
+// OttaORM hooks into devtools when available
+if (typeof window !== 'undefined' && window.__OTTABASE_DEVTOOLS__) {
+ window.__OTTABASE_DEVTOOLS__.queries.push({ sql, duration, model });
+}
+```
+
+**Effort:** M · **Impact:** 🟡 Medium
+
+---
+
+### 35. `@ottabase/docs-engine` — Full Documentation Site Engine
+
+**Description:** Extend `@ottabase/docs` into a full documentation platform: sidebar navigation from file system,
+versioned docs, Algolia DocSearch integration, MDX support, interactive playground via `@ottabase/ui-split-pane`.
+
+**Why:** Products with good documentation have lower churn and faster onboarding. Mintlify costs $150/month;
+a self-hosted docs engine that runs on the same Cloudflare Workers deployment is free.
+
+**Sample implementation:**
+
+```typescript
+// ottabase/config.ts — enable docs engine
+packages: {
+ docsEngine: {
+ enabled: true,
+ basePath: '/docs',
+ source: './content/docs', // Markdown files
+ search: 'algolia', // or 'd1-fts'
+ versions: ['v1', 'v2'],
+ }
+}
+```
+
+```tsx
+// Auto-generated sidebar, prev/next navigation, search
+// Accessed at /docs/getting-started, /docs/api-reference, etc.
+```
+
+**Effort:** L · **Impact:** 🟡 Medium
+
+---
+
+### 36. Enhancement: `@ottabase/cf-realtime` — Presence & Typing Indicators
+
+**Description:** Add user presence (online/offline/idle), per-document typing indicators, and cursor sharing to
+`@ottabase/cf-realtime`. Backed by Durable Objects. React hooks: `usePresence()`, `useTyping()`.
+
+**Why:** Collaborative editing, live dashboards, and shared kanban boards all need presence. Durable Objects already
+power the WebSocket layer — presence is a small surface extension with big perceived-value.
+
+**Sample implementation:**
+
+```typescript
+// packages/cf-realtime/src/presence.ts
+export const { usePresence } = createPresence({ channel: `doc:${docId}`, userId });
+
+const { online } = usePresence();
+// → [{ userId: 'u1', name: 'Alice', cursor: { x, y } }, ...]
+```
+
+```typescript
+const { isTyping, startTyping } = useTyping({ channel: `doc:${docId}`, userId });
+
+{isTyping.length > 0 && {isTyping.map(u => u.name).join(', ')} is typing...
}
+```
+
+**Effort:** S · **Impact:** 🟡 Medium
+
+---
+
+### 37. Enhancement: `@ottabase/ottaorm` — Optimistic Locking & Versioning
+
+**Description:** Add `version` column support to `BaseModel` for optimistic concurrency control. Concurrent updates
+increment the version; a stale update throws `ConflictError`. Also adds `history()` method for change tracking.
+
+**Why:** Multi-user collaborative editing (kanban, docs) without optimistic locking causes silent data loss. This is
+a one-time `BaseModel` primitive that prevents entire classes of race condition bugs.
+
+**Sample implementation:**
+
+```typescript
+// Opt-in per model
+export class Document extends BaseModel {
+ static optimisticLock = true; // adds `version` column
+
+ async update(data: Partial) {
+ // Throws ConflictError if version mismatch
+ return super.update({ ...data, version: this.get('version') + 1 });
+ }
+}
+```
+
+**Effort:** S · **Impact:** 🟠 High
+
+---
+
+### 38. Enhancement: `@ottabase/analytics` — Funnel & Cohort Analysis UI
+
+**Description:** Add pre-built React dashboard components to `@ottabase/analytics`: funnel visualisation, cohort
+retention heatmap, top-K tables, and a real-time event stream viewer. Data from Cloudflare WAE.
+
+**Why:** Raw WAE write calls are already wired. The missing piece is the read-side UI. Solo devs should be able to
+see their funnel and retention data without self-hosting Metabase.
+
+**Sample implementation:**
+
+```tsx
+import { FunnelChart, RetentionHeatmap, TopKTable } from '@ottabase/analytics/react';
+
+
+
+
+```
+
+**Effort:** M · **Impact:** 🟠 High
+
+---
+
+### 39. Enhancement: `@ottabase/queue` — Dead Letter Queue & Monitoring UI
+
+**Description:** Add DLQ support (failed jobs routed to separate queue after N retries), a `QueueJob` fat model for
+job persistence and query, and an admin UI showing queue depth, throughput, and failed job replay.
+
+**Why:** Job queues in production fail silently. Without DLQ and observability, failed background jobs (emails,
+webhooks, AI tasks) disappear without a trace. Visibility is non-negotiable for production.
+
+**Sample implementation:**
+
+```typescript
+// packages/queue/src/dlq.ts
+export async function handleJobFailure(job: QueueMessage, error: Error) {
+ const attempts = job.metadata?.attempts ?? 0;
+ if (attempts >= MAX_RETRIES) {
+ await DeadLetterJob.create({ jobId: job.id, payload: job.body, error: error.message });
+ await notify('team', `Job ${job.id} moved to DLQ: ${error.message}`);
+ }
+}
+```
+
+```tsx
+// Admin UI — queue dashboard
+
+```
+
+**Effort:** M · **Impact:** 🟠 High
+
+---
+
+### 40. Enhancement: Multi-App CLI & Deployment Orchestration
+
+**Description:** Extend `@ottabase/scripts` with `pnpm deploy:all` (parallel Wrangler deploys), `pnpm db:migrate`
+(run migrations across all D1 databases), and `pnpm status` (live deployment health from Cloudflare API).
+
+**Why:** Managing multiple apps in the monorepo becomes painful without deployment tooling. A solo dev running 3+
+apps should be able to deploy them all and check their status in a single command.
+
+**Sample implementation:**
+
+```bash
+pnpm deploy:all
+# → Deploying apps/my-saas ... ✓ 3.2s
+# → Deploying apps/my-homepage ... ✓ 2.1s
+# → Deploying apps/my-blog ... ✓ 1.8s
+# All 3 apps deployed successfully
+
+pnpm db:migrate --env production
+# → Running migrations for my-saas ... ✓ 2 new tables
+# → Running migrations for my-homepage... ✓ no changes
+```
+
+**Effort:** S · **Impact:** 🟠 High
+
+---
+
+## Summary Matrix
+
+| # | Package / Feature | Year | Effort | Impact |
+|---|---|---|---|---|
+| 1 | `@ottabase/payments` | Y1 | L | 🔴 |
+| 2 | `@ottabase/feature-flags` | Y1 | M | 🟠 |
+| 3 | `@ottabase/api-keys` | Y1 | M | 🟠 |
+| 4 | `@ottabase/ui-data-table` | Y1 | M | 🟠 |
+| 5 | `@ottabase/webhooks` | Y1 | M | 🟠 |
+| 6 | `@ottabase/waitlist` | Y1 | S | 🟠 |
+| 7 | `@ottabase/mfa` | Y1 | M | 🟠 |
+| 8 | `@ottabase/feedback` | Y1 | S | 🟡 |
+| 9 | `@ottabase/changelog` | Y1 | S | 🟡 |
+| 10 | `@ottabase/ui-onboarding` | Y1 | S | 🟠 |
+| 11 | `@ottabase/search` | Y1 | L | 🟠 |
+| 12 | `@ottabase/health` | Y1 | XS | 🟡 |
+| 13 | `@ottabase/backups` | Y1 | S | 🟠 |
+| 14 | `@ottabase/ui-charts` | Y1 | S | 🟡 |
+| 15 | `@ottabase/invitations` | Y1 | S | 🟠 |
+| 16 | `@ottabase/support` | Y1 | M | 🟡 |
+| 17 | OttaORM: Soft Deletes & Scopes | Y1 | S | 🟠 |
+| 18 | ottablog: RSS + Sitemap + Comments | Y1 | S | 🟡 |
+| 19 | brand-engine: Visual Token Editor | Y1 | M | 🟡 |
+| 20 | scripts: Interactive `create-app` CLI | Y1 | S | 🟠 |
+| 21 | `@ottabase/ai` | Y2 | M | 🟠 |
+| 22 | `@ottabase/embeddings` | Y2 | M | 🟡 |
+| 23 | `@ottabase/ai-content` | Y2 | M | 🟡 |
+| 24 | `@ottabase/pages` | Y2 | XL | 🟠 |
+| 25 | `@ottabase/billing-ui` | Y2 | M | 🟠 |
+| 26 | `@ottabase/affiliate` | Y2 | M | 🟡 |
+| 27 | `@ottabase/usage-metering` | Y2 | S | 🟠 |
+| 28 | `@ottabase/sso` | Y2 | L | 🟡 |
+| 29 | `@ottabase/ui-kanban` | Y2 | M | 🟡 |
+| 30 | `@ottabase/ui-calendar` | Y2 | L | 🟡 |
+| 31 | `@ottabase/testimonials` | Y2 | S | 🟡 |
+| 32 | `@ottabase/announcements` | Y2 | S | 🟡 |
+| 33 | `@ottabase/ottamap` | Y2 | S | 🟢 |
+| 34 | `@ottabase/devtools` | Y2 | M | 🟡 |
+| 35 | `@ottabase/docs-engine` | Y2 | L | 🟡 |
+| 36 | cf-realtime: Presence & Typing | Y2 | S | 🟡 |
+| 37 | OttaORM: Optimistic Locking | Y2 | S | 🟠 |
+| 38 | analytics: Funnel & Cohort UI | Y2 | M | 🟠 |
+| 39 | queue: DLQ & Monitoring UI | Y2 | M | 🟠 |
+| 40 | Multi-app Deploy Orchestration | Y2 | S | 🟠 |
+
+---
+
+> All packages follow the Ottabase conventions: OttaORM fat models, `workspace:*` deps, edge-safe code, README +
+> tests required. See `AGENTS.MD` and `PACKAGE_CREATION_GUIDE.md` for scaffolding instructions.