docs: add platform acceleration ideas for sub-day MVP onboarding
This commit is contained in:
parent
ce71c61079
commit
2b7e4819e8
796
docs/BEST_PRACTICES/PLATFORM_ACCELERATION_IDEAS.md
Normal file
796
docs/BEST_PRACTICES/PLATFORM_ACCELERATION_IDEAS.md
Normal file
@ -0,0 +1,796 @@
|
||||
# Platform Acceleration — From Days to Hours
|
||||
|
||||
> **Goal:** Reduce new product onboarding from 3–5 days to **under 8 hours** by making the platform do even more heavy lifting.
|
||||
>
|
||||
> **Date:** 2026-02-28 · **Status:** Proposal / Ideas
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Current Bottlenecks](#1-current-bottlenecks)
|
||||
2. [Tier 1 — CLI Scaffolding (saves Day 0–1)](#2-tier-1--cli-scaffolding-saves-day-01)
|
||||
3. [Tier 2 — Sync Engine as a Package (saves Day 3)](#3-tier-2--sync-engine-as-a-package-saves-day-3)
|
||||
4. [Tier 3 — Module Generator (saves Day 2)](#4-tier-3--module-generator-saves-day-2)
|
||||
5. [Tier 4 — Shared Auth UI Kit (saves Day 1)](#5-tier-4--shared-auth-ui-kit-saves-day-1)
|
||||
6. [Tier 5 — Universal User Dashboard Shell (saves Day 3)](#6-tier-5--universal-user-dashboard-shell-saves-day-3)
|
||||
7. [Tier 6 — Native SDKs (saves Day 4)](#7-tier-6--native-sdks-saves-day-4)
|
||||
8. [Tier 7 — Product Manifest (saves Day 0)](#8-tier-7--product-manifest-saves-day-0)
|
||||
9. [Tier 8 — Declarative Backend Modules](#9-tier-8--declarative-backend-modules)
|
||||
10. [Tier 9 — Platform Improvements (ongoing)](#10-tier-9--platform-improvements-ongoing)
|
||||
11. [Revised Timeline — The 8-Hour MVP](#11-revised-timeline--the-8-hour-mvp)
|
||||
12. [Implementation Priority](#12-implementation-priority)
|
||||
|
||||
---
|
||||
|
||||
## 1. Current Bottlenecks
|
||||
|
||||
Even with the platform, here's where time is still spent on each new product:
|
||||
|
||||
| Task | Current Time | Why It's Slow |
|
||||
| ----------------------------------------------------------------- | -------------------- | ------------------------------------------------------- |
|
||||
| Repo scaffolding (structure, configs, AGENTS.md) | 1–2 hours | Manual copy-paste from existing product, then customize |
|
||||
| Wiring `src/lib/` files (cosmos, auth, config, client, telemetry) | 1–2 hours | Same 6 files copied and tweaked every time |
|
||||
| Backend modules (types → repo → routes → test) | 2–4 hours per module | Boilerplate pattern is identical, only schemas differ |
|
||||
| Offline sync queue | 2–3 hours | Copied and adapted from product to product |
|
||||
| Native app auth + telemetry wiring | 3–4 hours | Same Swift/Kotlin files rewritten each time |
|
||||
| User dashboard (if needed) | 4–6 hours | Same Next.js shell with auth, nav, billing pages |
|
||||
| AGENTS.md creation | 30–60 minutes | Repetitive structure, product-specific values differ |
|
||||
| Design token setup | 1 hour | JSON → generator → theme files |
|
||||
| Error/not-found/middleware pages | 30 minutes | Literally identical across all dashboards |
|
||||
|
||||
**Total repeated work per product: ~15–25 hours.**
|
||||
|
||||
Below are concrete ideas to eliminate nearly all of it.
|
||||
|
||||
---
|
||||
|
||||
## 2. Tier 1 — CLI Scaffolding (saves Day 0–1)
|
||||
|
||||
### What
|
||||
|
||||
A CLI tool (`npx @bytelyst/create-app` or `pnpm dlx @bytelyst/create-app`) that:
|
||||
|
||||
1. Asks a few questions (product name, ID, bundle ID, platforms, features needed)
|
||||
2. Generates the entire repo structure
|
||||
3. Wires all `src/lib/` files with correct product ID
|
||||
4. Creates `.env.example` with all required vars
|
||||
5. Generates AGENTS.md, CLAUDE.md, .cursorrules, .windsurfrules from a template
|
||||
6. Creates `package.json` with correct `file:` refs
|
||||
7. Initializes git, creates first commit
|
||||
|
||||
### Scope
|
||||
|
||||
```
|
||||
@bytelyst/create-app/
|
||||
├── templates/
|
||||
│ ├── nextjs-web/ # Next.js 16 App Router template
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── app/
|
||||
│ │ │ │ ├── layout.tsx # With providers, metadata
|
||||
│ │ │ │ ├── page.tsx # Landing page
|
||||
│ │ │ │ ├── error.tsx # Error boundary
|
||||
│ │ │ │ ├── not-found.tsx
|
||||
│ │ │ │ └── providers.tsx
|
||||
│ │ │ ├── lib/
|
||||
│ │ │ │ ├── cosmos.ts # Template with {{PRODUCT_ID}}
|
||||
│ │ │ │ ├── auth-server.ts
|
||||
│ │ │ │ ├── product-config.ts
|
||||
│ │ │ │ ├── platform-client.ts
|
||||
│ │ │ │ ├── telemetry.ts
|
||||
│ │ │ │ └── middleware.ts
|
||||
│ │ │ └── styles/globals.css
|
||||
│ │ └── package.json.tmpl
|
||||
│ ├── expo-rn/ # Expo + React Native template
|
||||
│ │ ├── src/
|
||||
│ │ │ ├── app/_layout.tsx
|
||||
│ │ │ ├── api/ # Standard API wrappers
|
||||
│ │ │ ├── lib/
|
||||
│ │ │ │ ├── telemetry.ts
|
||||
│ │ │ │ └── offline-queue.ts
|
||||
│ │ │ └── store/
|
||||
│ │ │ ├── mmkv-storage.ts
|
||||
│ │ │ └── user-store.ts
|
||||
│ │ └── app.json.tmpl
|
||||
│ ├── swiftui-ios/ # SwiftUI template
|
||||
│ ├── compose-android/ # Jetpack Compose template
|
||||
│ └── agents-md/ # AGENTS.md generator template
|
||||
├── src/
|
||||
│ ├── cli.ts # Interactive prompts
|
||||
│ ├── scaffold.ts # File generation
|
||||
│ └── register.ts # Auto-register product in platform-service
|
||||
└── package.json
|
||||
```
|
||||
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
$ npx @bytelyst/create-app
|
||||
|
||||
? Product name: FocusPal
|
||||
? Product ID: focuspal
|
||||
? Bundle ID: com.saravana.focuspal
|
||||
? Platforms: [x] Web (Next.js) [x] iOS (SwiftUI) [ ] Android [x] Expo (React Native)
|
||||
? Features: [x] Auth [x] Billing [x] Telemetry [x] Feature flags [x] Offline sync
|
||||
? User dashboard? Yes
|
||||
|
||||
✓ Created learning_ai_focuspal/
|
||||
✓ Generated web/ with Next.js 16 + @bytelyst/* wiring
|
||||
✓ Generated ios/ scaffold with TelemetryService + PlatformSyncManager
|
||||
✓ Generated AGENTS.md, CLAUDE.md, .cursorrules, .windsurfrules
|
||||
✓ Registered product "focuspal" in platform-service
|
||||
✓ Seeded default feature flags for focuspal
|
||||
✓ Added to workspace backup scripts
|
||||
✓ First commit: "chore: scaffold FocusPal product"
|
||||
|
||||
Next steps:
|
||||
cd learning_ai_focuspal/web && npm install && npm run dev
|
||||
```
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 3–4 hours of manual scaffolding
|
||||
- **After:** 5 minutes interactive CLI → fully wired repo
|
||||
|
||||
---
|
||||
|
||||
## 3. Tier 2 — Sync Engine as a Package (saves Day 3)
|
||||
|
||||
### The Problem
|
||||
|
||||
Every product re-implements the same sync pattern:
|
||||
|
||||
| Product | Sync Files | Lines |
|
||||
| ---------- | ------------------------------------------------ | ----- |
|
||||
| ChronoMind | `platform-sync.ts`, `use-sync.ts` | ~400 |
|
||||
| NomGap | `offline-queue.ts`, sync in `fasting-store.ts` | ~250 |
|
||||
| MindLyst | `PlatformSyncManager.kt`, `PlatformApiClient.kt` | ~300 |
|
||||
|
||||
All three do the same thing: local-first writes → background sync → offline queue → conflict detection → pull remote.
|
||||
|
||||
### The Solution: `@bytelyst/sync`
|
||||
|
||||
A new shared package that provides a configurable sync engine:
|
||||
|
||||
```typescript
|
||||
// @bytelyst/sync — usage in a product
|
||||
import { createSyncEngine } from '@bytelyst/sync';
|
||||
|
||||
const sync = createSyncEngine({
|
||||
productId: 'focuspal',
|
||||
entities: {
|
||||
tasks: {
|
||||
endpoint: '/tasks',
|
||||
partitionKey: 'userId',
|
||||
conflictStrategy: 'server-wins', // or 'client-wins', 'manual'
|
||||
},
|
||||
projects: {
|
||||
endpoint: '/projects',
|
||||
partitionKey: 'userId',
|
||||
conflictStrategy: 'last-write-wins',
|
||||
},
|
||||
},
|
||||
storage: localStorage, // or MMKV, AsyncStorage
|
||||
apiClient: platformClient, // from @bytelyst/api-client
|
||||
onConflict: (local, remote) => {
|
||||
/* custom merge */
|
||||
},
|
||||
});
|
||||
|
||||
// In your store:
|
||||
sync.push('tasks', newTask); // Enqueues for sync
|
||||
sync.delete('tasks', taskId);
|
||||
await sync.pull(); // Fetch remote changes
|
||||
await sync.fullSync(); // Bidirectional sync
|
||||
sync.getQueueLength(); // Pending changes count
|
||||
```
|
||||
|
||||
### What It Handles
|
||||
|
||||
- **Offline queue** with MMKV/localStorage/AsyncStorage persistence
|
||||
- **Retry with exponential backoff** (max 5 attempts per item)
|
||||
- **Conflict detection** — timestamp comparison, configurable strategy
|
||||
- **Bidirectional pull/push** — pull remote first, then push local
|
||||
- **Queue flush on reconnect** — `navigator.onLine` or app foreground event
|
||||
- **Deduplication** — collapse multiple updates to same entity
|
||||
- **Telemetry** — auto-tracks sync success/failure/conflicts via `@bytelyst/telemetry-client`
|
||||
|
||||
### Native Equivalents
|
||||
|
||||
- **Swift:** `SyncEngine` class with same API, using `UserDefaults` for queue
|
||||
- **Kotlin:** `SyncEngine` class with same API, using `SharedPreferences` for queue
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 4–6 hours copying and adapting sync code per product
|
||||
- **After:** `npm install @bytelyst/sync`, 20 lines of config
|
||||
|
||||
---
|
||||
|
||||
## 4. Tier 3 — Module Generator (saves Day 2)
|
||||
|
||||
### The Problem
|
||||
|
||||
Every platform-service module follows the exact same structure:
|
||||
|
||||
```
|
||||
modules/<name>/
|
||||
├── types.ts # Zod schema + interface
|
||||
├── repository.ts # Cosmos CRUD (list, get, create, update, delete)
|
||||
├── routes.ts # Fastify endpoints
|
||||
└── <name>.test.ts # Vitest tests
|
||||
```
|
||||
|
||||
Yet we write these by hand every time, copy-pasting from another module and renaming.
|
||||
|
||||
### The Solution: Schema-Driven Code Generation
|
||||
|
||||
A generator script in the platform-service that reads a schema definition and emits all 4 files:
|
||||
|
||||
```bash
|
||||
$ pnpm gen:module --name tasks --fields "title:string,status:enum(pending,active,done),priority:number,dueAt:date?" --partition userId
|
||||
```
|
||||
|
||||
Generates:
|
||||
|
||||
**types.ts:**
|
||||
|
||||
```typescript
|
||||
import { z } from 'zod';
|
||||
|
||||
export const TaskStatusEnum = z.enum(['pending', 'active', 'done']);
|
||||
export type TaskStatus = z.infer<typeof TaskStatusEnum>;
|
||||
|
||||
export interface TaskDoc {
|
||||
id: string;
|
||||
productId: string;
|
||||
userId: string;
|
||||
title: string;
|
||||
status: TaskStatus;
|
||||
priority: number;
|
||||
dueAt?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export const CreateTaskSchema = z.object({
|
||||
title: z.string().min(1).max(500),
|
||||
status: TaskStatusEnum.default('pending'),
|
||||
priority: z.number().int().min(0).max(10).default(5),
|
||||
dueAt: z.string().datetime().optional(),
|
||||
});
|
||||
|
||||
export const UpdateTaskSchema = CreateTaskSchema.partial();
|
||||
```
|
||||
|
||||
**repository.ts, routes.ts, and test file** — all generated with the correct entity name, partition key, and field references.
|
||||
|
||||
The generator also:
|
||||
|
||||
- Adds the Cosmos container to `cosmos-init.ts`
|
||||
- Registers the routes in `server.ts`
|
||||
- Adds the test file
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 2–4 hours per module (hand-writing 4 files, ~150–250 lines each)
|
||||
- **After:** One command, 5 seconds. Then customize the generated code as needed.
|
||||
|
||||
---
|
||||
|
||||
## 5. Tier 4 — Shared Auth UI Kit (saves Day 1)
|
||||
|
||||
### The Problem
|
||||
|
||||
Every product builds the same auth pages:
|
||||
|
||||
| Page | ChronoMind | NomGap | MindLyst | LysnrAI |
|
||||
| ---------------------- | ---------- | ---------- | ---------- | ---------- |
|
||||
| Login | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt |
|
||||
| Register | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt |
|
||||
| Forgot Password | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt | ✅ rebuilt |
|
||||
| SSO (Google/Microsoft) | partial | — | — | ✅ rebuilt |
|
||||
| Onboarding flow | ✅ custom | ✅ custom | ✅ custom | ✅ custom |
|
||||
|
||||
The logic is identical — only colors and copy differ.
|
||||
|
||||
### The Solution: `@bytelyst/auth-ui`
|
||||
|
||||
A shared React component library for auth flows:
|
||||
|
||||
```tsx
|
||||
// In your app's login page
|
||||
import { LoginPage, RegisterPage, ForgotPasswordPage } from '@bytelyst/auth-ui';
|
||||
|
||||
export default function Login() {
|
||||
return (
|
||||
<LoginPage
|
||||
productName="FocusPal"
|
||||
logo="/logo.svg"
|
||||
theme="dark" // uses your product's design tokens
|
||||
ssoProviders={['google']} // optional SSO buttons
|
||||
onSuccess={() => router.push('/dashboard')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Components included:
|
||||
|
||||
- `<LoginPage />` — email/password + SSO buttons + "forgot password" link
|
||||
- `<RegisterPage />` — name, email, password, confirm, terms checkbox
|
||||
- `<ForgotPasswordPage />` — email input → reset link sent
|
||||
- `<ResetPasswordPage />` — new password form (token from URL)
|
||||
- `<VerifyEmailPage />` — verification code input
|
||||
- `<OnboardingShell />` — multi-step wizard container (you provide the step content)
|
||||
|
||||
All pre-wired to `@bytelyst/auth-client` under the hood.
|
||||
|
||||
### Native Equivalents
|
||||
|
||||
- **SwiftUI:** `AuthFlowView(config:)` — same flows, native UI
|
||||
- **Compose:** `AuthScreen(config)` — Material 3 themed
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 4–6 hours building auth pages per product
|
||||
- **After:** Import, customize props, done in 30 minutes
|
||||
|
||||
---
|
||||
|
||||
## 6. Tier 5 — Universal User Dashboard Shell (saves Day 3)
|
||||
|
||||
### The Problem
|
||||
|
||||
Every product with a user-facing portal rebuilds the same shell:
|
||||
|
||||
- Sidebar/nav with route links
|
||||
- User profile page
|
||||
- Billing/subscription page
|
||||
- Settings/preferences page
|
||||
- API key management (if applicable)
|
||||
- Notification preferences
|
||||
|
||||
Only the product-specific pages differ.
|
||||
|
||||
### The Solution: `@bytelyst/dashboard-shell`
|
||||
|
||||
A configurable Next.js layout package that provides the universal pages out of the box:
|
||||
|
||||
```tsx
|
||||
// app/layout.tsx
|
||||
import { DashboardShell } from '@bytelyst/dashboard-shell';
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<DashboardShell
|
||||
productName="FocusPal"
|
||||
logo="/logo.svg"
|
||||
navItems={[
|
||||
{ label: 'Dashboard', href: '/dashboard', icon: 'home' },
|
||||
{ label: 'Tasks', href: '/tasks', icon: 'check-square' },
|
||||
// ... your product-specific pages
|
||||
]}
|
||||
features={{
|
||||
billing: true, // adds /billing page
|
||||
profile: true, // adds /profile page
|
||||
settings: true, // adds /settings page
|
||||
notifications: true, // adds /notifications preferences
|
||||
apiKeys: false, // no API key management
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</DashboardShell>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The shell provides:
|
||||
|
||||
- Responsive sidebar layout with mobile hamburger
|
||||
- Built-in pages: Profile, Billing (Stripe portal link), Settings, Notifications
|
||||
- Theme toggle (dark/light)
|
||||
- Keyboard shortcuts
|
||||
- Breadcrumbs
|
||||
- User avatar + dropdown menu
|
||||
- All pre-wired to `@bytelyst/auth-client` and `@bytelyst/api-client`
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 4–6 hours building the dashboard shell + universal pages
|
||||
- **After:** 1 import + config object. Only build your product-specific pages.
|
||||
|
||||
---
|
||||
|
||||
## 7. Tier 6 — Native SDKs (saves Day 4)
|
||||
|
||||
### The Problem
|
||||
|
||||
Each native app (iOS/Android) re-implements:
|
||||
|
||||
1. `TelemetryService` — event batching, flush, install ID persistence
|
||||
2. `PlatformApiClient` — auth header injection, retry, timeout
|
||||
3. `PlatformSyncManager` — offline queue, pull/push, conflict detection
|
||||
4. `AuthManager` — login, register, token storage, refresh
|
||||
5. `FeatureFlagManager` — polling, local cache, override support
|
||||
|
||||
These are copied between ChronoMind, MindLyst, NomGap, and LysnrAI with minor tweaks.
|
||||
|
||||
### The Solution: Swift Package + Kotlin Library
|
||||
|
||||
**Swift Package: `ByteLystSDK`**
|
||||
|
||||
```swift
|
||||
// Package.swift dependency
|
||||
.package(url: "https://github.com/bytelyst/bytelyst-ios-sdk", from: "1.0.0")
|
||||
|
||||
// In your app
|
||||
import ByteLystSDK
|
||||
|
||||
let platform = ByteLystPlatform(
|
||||
productId: "focuspal",
|
||||
baseUrl: "https://api.focuspal.app",
|
||||
authStorage: KeychainTokenStorage()
|
||||
)
|
||||
|
||||
// Auth
|
||||
try await platform.auth.login(email: email, password: password)
|
||||
|
||||
// Telemetry
|
||||
platform.telemetry.track("screen_view", module: "tasks", name: "task_list")
|
||||
|
||||
// Feature flags
|
||||
if platform.flags.isEnabled("new_task_ui") { ... }
|
||||
|
||||
// Sync
|
||||
platform.sync.register(entity: "tasks", endpoint: "/tasks")
|
||||
platform.sync.push(entity: "tasks", data: taskJSON)
|
||||
await platform.sync.fullSync()
|
||||
```
|
||||
|
||||
**Kotlin Library: `com.bytelyst.sdk`**
|
||||
|
||||
Same API surface, published to local Maven or GitHub Packages.
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 3–4 hours copying and adapting native files per app
|
||||
- **After:** One dependency, one init call
|
||||
|
||||
---
|
||||
|
||||
## 8. Tier 7 — Product Manifest (saves Day 0)
|
||||
|
||||
### The Idea
|
||||
|
||||
A single `product.json` file that defines everything about a product. All tooling reads from it:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "focuspal",
|
||||
"name": "FocusPal",
|
||||
"bundleId": "com.saravana.focuspal",
|
||||
"domain": "focuspal.app",
|
||||
"description": "AI-powered focus and task management",
|
||||
|
||||
"platforms": ["web", "ios", "android"],
|
||||
|
||||
"theme": {
|
||||
"accentPrimary": "#7C5CFF",
|
||||
"accentSecondary": "#FF6B8A",
|
||||
"bgCanvas": "#06070A",
|
||||
"surfaceCard": "#121725"
|
||||
},
|
||||
|
||||
"features": {
|
||||
"auth": true,
|
||||
"billing": true,
|
||||
"telemetry": true,
|
||||
"featureFlags": true,
|
||||
"offlineSync": true,
|
||||
"pushNotifications": true,
|
||||
"publicRoadmap": true
|
||||
},
|
||||
|
||||
"cosmos": {
|
||||
"containers": {
|
||||
"tasks": { "partitionKeyPath": "/userId" },
|
||||
"projects": { "partitionKeyPath": "/userId" },
|
||||
"focus_sessions": { "partitionKeyPath": "/userId" }
|
||||
}
|
||||
},
|
||||
|
||||
"defaultFlags": [
|
||||
{ "key": "focuspal_new_task_ui", "enabled": false, "description": "New task creation UI" },
|
||||
{ "key": "focuspal_ai_suggestions", "enabled": true, "description": "AI task suggestions" }
|
||||
],
|
||||
|
||||
"ports": {
|
||||
"web": 3060,
|
||||
"userDashboard": 3062
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This manifest is consumed by:
|
||||
|
||||
- **CLI scaffolder** — generates repo from manifest
|
||||
- **Platform-service** — auto-registers product, containers, flags on startup
|
||||
- **Design tokens generator** — produces theme files from `theme` block
|
||||
- **AGENTS.md generator** — populates product identity section
|
||||
- **CI/CD** — knows which platforms to build
|
||||
- **Docker compose** — assigns ports
|
||||
- **Backup scripts** — discovers repos
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** Product identity scattered across 10+ files
|
||||
- **After:** Single source of truth; everything derived from it
|
||||
|
||||
---
|
||||
|
||||
## 9. Tier 8 — Declarative Backend Modules
|
||||
|
||||
### The Vision
|
||||
|
||||
Instead of writing `types.ts → repository.ts → routes.ts → test.ts` for every entity, define modules declaratively:
|
||||
|
||||
```yaml
|
||||
# modules/tasks.module.yaml
|
||||
name: tasks
|
||||
container: tasks
|
||||
partitionKey: /userId
|
||||
|
||||
fields:
|
||||
title:
|
||||
type: string
|
||||
min: 1
|
||||
max: 500
|
||||
required: true
|
||||
status:
|
||||
type: enum
|
||||
values: [pending, active, completed, archived]
|
||||
default: pending
|
||||
priority:
|
||||
type: integer
|
||||
min: 0
|
||||
max: 10
|
||||
default: 5
|
||||
dueAt:
|
||||
type: datetime
|
||||
optional: true
|
||||
tags:
|
||||
type: string[]
|
||||
optional: true
|
||||
|
||||
endpoints:
|
||||
list:
|
||||
method: GET
|
||||
path: /tasks
|
||||
auth: user
|
||||
filter: [status, priority]
|
||||
sort: [createdAt, dueAt, priority]
|
||||
pagination: true
|
||||
|
||||
get:
|
||||
method: GET
|
||||
path: /tasks/:id
|
||||
auth: user
|
||||
|
||||
create:
|
||||
method: POST
|
||||
path: /tasks
|
||||
auth: user
|
||||
|
||||
update:
|
||||
method: PATCH
|
||||
path: /tasks/:id
|
||||
auth: user
|
||||
|
||||
delete:
|
||||
method: DELETE
|
||||
path: /tasks/:id
|
||||
auth: user
|
||||
|
||||
# Custom endpoint
|
||||
bulk-complete:
|
||||
method: POST
|
||||
path: /tasks/bulk-complete
|
||||
auth: user
|
||||
custom: true # generates stub for manual implementation
|
||||
```
|
||||
|
||||
A runtime module loader reads these YAML files and generates Fastify routes at startup. Standard CRUD is fully automatic; custom endpoints get generated stubs.
|
||||
|
||||
### Hybrid Approach
|
||||
|
||||
For simpler CRUD modules, the YAML approach eliminates code entirely. For complex modules (auth, billing, telemetry), hand-written code remains. This is the same pattern used by tools like Prisma, Hasura, or Strapi — but tailored to our Fastify + Cosmos stack.
|
||||
|
||||
### Impact
|
||||
|
||||
- **Before:** 2–4 hours per CRUD module
|
||||
- **After:** Write a YAML file (10 minutes). Zero TypeScript for standard CRUD.
|
||||
|
||||
---
|
||||
|
||||
## 10. Tier 9 — Platform Improvements (ongoing)
|
||||
|
||||
### 10.1 Auto-Registration on First Request
|
||||
|
||||
Instead of manually registering containers, feature flags, and product identity — detect new `productId` values at runtime and auto-provision:
|
||||
|
||||
```
|
||||
First request with productId: "focuspal" →
|
||||
1. Create product doc if not exists
|
||||
2. Create Cosmos containers from manifest
|
||||
3. Seed default feature flags
|
||||
4. Log to audit
|
||||
```
|
||||
|
||||
### 10.2 Shared Error/Loading/NotFound Components
|
||||
|
||||
Every dashboard currently has its own `error.tsx`, `not-found.tsx`, and loading states. These are identical. Publish them in a shared package:
|
||||
|
||||
```tsx
|
||||
// @bytelyst/dashboard-components
|
||||
export {
|
||||
ErrorPage,
|
||||
NotFoundPage,
|
||||
LoadingSpinner,
|
||||
EmptyState,
|
||||
} from '@bytelyst/dashboard-components';
|
||||
```
|
||||
|
||||
### 10.3 API Route Template Generator
|
||||
|
||||
Next.js API routes follow a pattern too. Generate them:
|
||||
|
||||
```bash
|
||||
$ npx @bytelyst/gen:api-route --name tasks --methods GET,POST,PATCH,DELETE
|
||||
# → Generates src/app/api/tasks/route.ts and src/app/api/tasks/[id]/route.ts
|
||||
```
|
||||
|
||||
### 10.4 Webhook/Event Subscription Auto-Wiring
|
||||
|
||||
When a product registers interest in events (e.g., `user.created`, `subscription.updated`), the platform auto-delivers them via the event bus — no manual wiring.
|
||||
|
||||
### 10.5 Multi-Product Telemetry Dashboard
|
||||
|
||||
The current telemetry viewer shows one product at a time. A cross-product view would show:
|
||||
|
||||
- Total events/day across all products
|
||||
- Error rates per product
|
||||
- Feature adoption comparison
|
||||
- User overlap (same user across products)
|
||||
|
||||
### 10.6 Shared Onboarding Analytics
|
||||
|
||||
Track onboarding funnel (step 1 → step 2 → ... → complete) as a platform feature, not per-product code:
|
||||
|
||||
```typescript
|
||||
platform.onboarding.trackStep('focuspal', userId, 'welcome', 1);
|
||||
platform.onboarding.trackStep('focuspal', userId, 'select_plan', 2);
|
||||
platform.onboarding.trackComplete('focuspal', userId);
|
||||
```
|
||||
|
||||
Admin dashboard shows conversion funnels per product automatically.
|
||||
|
||||
### 10.7 Pre-Built Stripe Checkout Flow
|
||||
|
||||
Instead of each product building Stripe checkout integration, provide a universal checkout endpoint:
|
||||
|
||||
```
|
||||
POST /billing/checkout
|
||||
{
|
||||
"productId": "focuspal",
|
||||
"userId": "user_123",
|
||||
"priceId": "price_abc",
|
||||
"successUrl": "https://focuspal.app/billing?success=true",
|
||||
"cancelUrl": "https://focuspal.app/billing"
|
||||
}
|
||||
→ Returns Stripe checkout session URL
|
||||
```
|
||||
|
||||
Client just redirects — no Stripe SDK needed on the client.
|
||||
|
||||
---
|
||||
|
||||
## 11. Revised Timeline — The 8-Hour MVP
|
||||
|
||||
With the accelerators above implemented, here's what a new product launch looks like:
|
||||
|
||||
| Time | Task | How |
|
||||
| ------------- | ---------------------------------------- | --------------------------------------------------- |
|
||||
| **0:00–0:15** | Create product manifest (`product.json`) | Write 40 lines of JSON |
|
||||
| **0:15–0:30** | Run CLI scaffolder | `npx @bytelyst/create-app --from product.json` |
|
||||
| **0:30–1:00** | Define backend modules | Write 2–3 YAML module definitions |
|
||||
| **1:00–1:30** | Customize landing page + dashboard pages | Product-specific UI only |
|
||||
| **1:30–3:00** | Build core product screens (3–5 screens) | The actual unique product logic |
|
||||
| **3:00–4:00** | Native app scaffolding | CLI generates iOS/Android shells with SDK pre-wired |
|
||||
| **4:00–5:00** | Write engine tests | Pure function tests for product logic |
|
||||
| **5:00–6:00** | Polish, theme customization | Tweak colors in manifest, regenerate tokens |
|
||||
| **6:00–7:00** | E2E smoke test, typecheck, build verify | Automated checks |
|
||||
| **7:00–8:00** | First deploy, seed data, verify in prod | Docker/Netlify/Vercel deploy |
|
||||
|
||||
### What You Write vs What the Platform Provides
|
||||
|
||||
```
|
||||
YOUR CODE (~20% of total) PLATFORM CODE (~80% of total)
|
||||
───────────────────────── ────────────────────────────
|
||||
product.json (manifest) Auth (login, register, SSO, password reset)
|
||||
2–3 YAML module defs Billing (Stripe, plans, subscriptions)
|
||||
3–5 product screens Telemetry (client SDK, server ingestion, admin UI)
|
||||
Product engine logic (src/lib/) Feature flags (rollout, polling, admin)
|
||||
Custom API routes (if any) Offline sync engine
|
||||
Theme overrides Admin dashboard (users, audit, flags, telemetry)
|
||||
Tracker dashboard (roadmap, issues, voting)
|
||||
User dashboard shell (profile, billing, settings)
|
||||
Auth UI (login, register, forgot password)
|
||||
Error/loading/not-found pages
|
||||
GDPR data export
|
||||
Email delivery + templates
|
||||
Rate limiting + IP rules
|
||||
Maintenance mode + status page
|
||||
Health checks + monitoring
|
||||
Audit logging
|
||||
Blob storage
|
||||
CI/CD templates
|
||||
Native SDKs (iOS, Android)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Implementation Priority
|
||||
|
||||
### Phase 1: Highest Impact, Lowest Effort (1–2 weeks)
|
||||
|
||||
| # | Accelerator | Effort | Impact |
|
||||
| --- | --------------------------------------------- | ------ | ----------------------------------------- |
|
||||
| 1 | **Product manifest** (`product.json` spec) | 2 days | Foundation for everything else |
|
||||
| 2 | **Module generator** (`pnpm gen:module`) | 2 days | Eliminates 2–4 hours per module |
|
||||
| 3 | **Shared error/loading/not-found components** | 1 day | Eliminates copy-paste across 5 dashboards |
|
||||
| 4 | **Sync engine package** (`@bytelyst/sync`) | 3 days | Eliminates ~400 lines per product |
|
||||
|
||||
### Phase 2: High Impact, Medium Effort (2–4 weeks)
|
||||
|
||||
| # | Accelerator | Effort | Impact |
|
||||
| --- | ------------------------------------------- | ------ | ---------------------------------- |
|
||||
| 5 | **CLI scaffolder** (`@bytelyst/create-app`) | 1 week | Day 0 → 15 minutes |
|
||||
| 6 | **Auth UI kit** (`@bytelyst/auth-ui`) | 1 week | Eliminates auth page rebuilds |
|
||||
| 7 | **API route generator** | 2 days | Eliminates Next.js API boilerplate |
|
||||
|
||||
### Phase 3: Game-Changers, Higher Effort (1–2 months)
|
||||
|
||||
| # | Accelerator | Effort | Impact |
|
||||
| --- | ------------------------------------------------- | ------- | ---------------------------------------- |
|
||||
| 8 | **Dashboard shell** (`@bytelyst/dashboard-shell`) | 2 weeks | Eliminates entire user dashboard rebuild |
|
||||
| 9 | **Native SDKs** (Swift + Kotlin) | 2 weeks | Eliminates native boilerplate entirely |
|
||||
| 10 | **Declarative YAML modules** | 2 weeks | Zero-code CRUD modules |
|
||||
| 11 | **Auto-registration on first request** | 3 days | Zero manual provisioning |
|
||||
|
||||
### Phase 4: Polish & Scale
|
||||
|
||||
| # | Accelerator | Effort | Impact |
|
||||
| --- | -------------------------------------- | ------ | ---------------------------- |
|
||||
| 12 | Multi-product telemetry dashboard | 1 week | Cross-product visibility |
|
||||
| 13 | Shared onboarding analytics | 3 days | Automatic funnel tracking |
|
||||
| 14 | Pre-built Stripe checkout flow | 2 days | Zero client-side Stripe code |
|
||||
| 15 | AGENTS.md auto-generator from manifest | 1 day | Always up-to-date agent docs |
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The current platform already provides ~85% reduction in time-to-MVP compared to building from scratch. With the accelerators proposed above:
|
||||
|
||||
| Metric | Current | After Phase 1–2 | After Phase 3–4 |
|
||||
| ---------------------------- | ------------------- | ---------------------- | -------------------- |
|
||||
| **Time to MVP** | 3–5 days | 1–2 days | **4–8 hours** |
|
||||
| **Lines you write** | ~3,000 | ~1,500 | **~500** |
|
||||
| **Files you create** | ~40 | ~20 | **~10** |
|
||||
| **Backend modules (manual)** | Hand-written | Generated + customized | **Declarative YAML** |
|
||||
| **Auth UI** | Rebuilt per product | Shared components | Shared components |
|
||||
| **Sync engine** | Copied per product | Shared package | Shared package |
|
||||
| **Native wiring** | Copied per product | Native SDK | Native SDK |
|
||||
|
||||
The key insight: **you should only write code that is unique to your product.** Everything else — auth, billing, telemetry, sync, dashboards, error pages, CRUD modules, native wiring — should be a platform capability that you configure, not code you write.
|
||||
Loading…
Reference in New Issue
Block a user