29 KiB
Platform Acceleration — Implementation Roadmap
Companion to: PLATFORM_ACCELERATION_IDEAS.md
Purpose: Concrete phased roadmap with task lists, timelines, dependencies, and acceptance criteria so we never lose track of these aspirational improvements.
Date: 2026-02-28 · Status: Planned
Table of Contents
- Overview & Phasing
- Phase 1 — Foundation (Weeks 1–2)
- Phase 2 — Developer Experience (Weeks 3–6)
- Phase 3 — Native & Declarative (Weeks 7–12)
- Phase 4 — Polish & Scale (Weeks 13–16)
- Dependency Graph
- Success Metrics
- Risk Register
1. Overview & Phasing
Phase 1 (Wk 1-2) Phase 2 (Wk 3-6) Phase 3 (Wk 7-12) Phase 4 (Wk 13-16)
───────────────── ───────────────── ────────────────── ──────────────────
Product manifest CLI scaffolder Native Swift SDK Multi-product telemetry
Module generator Auth UI kit Native Kotlin SDK Onboarding analytics
Shared UI components API route generator Dashboard shell Pre-built Stripe checkout
Sync engine package AGENTS.md auto-gen Declarative YAML modules Auto-registration
Cross-product dashboards
Target outcome: New product from zero → deployed MVP in under 8 hours.
2. Phase 1 — Foundation (Weeks 1–2)
Theme: Build the primitives that everything else depends on.
2.1 Product Manifest Specification (product.json)
What: Define a JSON schema that captures everything about a product — identity, theme, features, containers, flags, ports.
Location: packages/config/src/product-manifest.ts
Tasks:
- Design
product.jsonJSON schema (Zod) - Define fields:
id,name,bundleId,domain,description,platforms[],theme{},features{},cosmos.containers{},defaultFlags[],ports{} - Add
loadProductManifest(path)function to@bytelyst/config - Add validation: all required fields, valid productId format, no duplicate container names
- Write tests (8–10 tests)
- Create
product.jsonfiles for existing products: LysnrAI, MindLyst, ChronoMind, NomGap - Document the schema in README
Acceptance Criteria:
loadProductManifest('./product.json')returns typed, validated config- Existing products have valid manifests
- Schema is extensible (unknown keys don't fail validation)
Estimated effort: 2 days Dependencies: None Blocks: Phase 2 CLI scaffolder, Phase 4 auto-registration
2.2 Module Generator (pnpm gen:module)
What: A script that generates the standard types.ts → repository.ts → routes.ts → test.ts module from a field definition.
Location: services/platform-service/scripts/gen-module.ts
Tasks:
- Design CLI interface:
pnpm gen:module --name <name> --fields "<field:type,...>" --partition <key> - Support field types:
string,number,boolean,date,datetime,enum(a,b,c),string[],number[] - Support optional fields with
?suffix (e.g.,dueAt:datetime?) - Generate
types.tswith Zod schemas (Create*Schema,Update*Schema) and TypeScript interface - Generate
repository.tswith list/get/create/update/delete functions - Generate
routes.tswith GET (list), GET/:id, POST, PATCH/:id, DELETE/:id - Generate
<module>.test.tswith tests for all CRUD operations - Auto-add container to
cosmos-init.tsCONTAINER_DEFS - Auto-add route import + registration to
server.ts - Add
--dry-runflag to preview output without writing files - Write tests for the generator itself (template rendering)
- Add
gen:modulescript to platform-servicepackage.json
Acceptance Criteria:
pnpm gen:module --name tasks --fields "title:string,status:enum(pending,active,done),priority:number" --partition userIdproduces 4 valid files- Generated code passes
pnpm typecheckandpnpm testwith no modifications - Container automatically appears in
cosmos-init.ts - Route automatically registered in
server.ts
Estimated effort: 2 days Dependencies: None Blocks: Phase 3 declarative YAML modules
2.3 Shared UI Components Package
What: Extract identical components used across all dashboards into a shared package.
Location: packages/dashboard-components/
Tasks:
- Create
packages/dashboard-components/package structure - Extract
ErrorPagecomponent (currently copy-pasted in admin-web, tracker-web, user-dashboard-web) - Extract
NotFoundPagecomponent - Extract
LoadingSpinner/LoadingSkeletoncomponent - Extract
EmptyStatecomponent (icon + title + description + CTA) - Extract
PageHeadercomponent (title + breadcrumbs + actions) - Make all components theme-aware (accept CSS custom properties)
- Write Storybook-like visual tests or snapshot tests
- Update admin-web to consume from
@bytelyst/dashboard-components - Update tracker-web to consume
- Update user-dashboard-web to consume
- Add package to
pnpm-workspace.yaml - Document usage in README
Acceptance Criteria:
- All 3 dashboards import from
@bytelyst/dashboard-componentsinstead of local copies - Components render correctly with each dashboard's theme
- Zero visual regression (screenshots match before/after)
Estimated effort: 2 days Dependencies: None Blocks: Phase 3 dashboard shell
2.4 Sync Engine Package (@bytelyst/sync)
What: Extract the offline-first sync pattern into a reusable package with configurable entities, conflict strategies, and storage adapters.
Location: packages/sync/
Tasks:
- Audit existing sync implementations:
- ChronoMind:
web/src/lib/platform-sync.ts(~200 lines),use-sync.ts - NomGap:
src/lib/offline-queue.ts(~150 lines), store sync infasting-store.ts - MindLyst:
PlatformSyncManager.kt,PlatformApiClient.kt
- ChronoMind:
- Design unified API:
createSyncEngine({ productId, entities, storage, apiClient, onConflict }) engine.push(entity, data) engine.delete(entity, id) engine.pull() → Promise<SyncResult> engine.fullSync() → Promise<SyncResult> engine.getQueueLength() → number engine.onStatusChange(callback) - Implement offline queue with configurable storage adapter:
LocalStorageAdapter(web)MMKVAdapter(React Native) — interface only, consumer provides MMKV instanceInMemoryAdapter(testing)
- Implement retry with exponential backoff (max 5 attempts, configurable)
- Implement conflict detection (timestamp-based)
- Implement conflict strategies:
server-wins,client-wins,last-write-wins,manual - Implement queue deduplication (collapse multiple updates to same entity)
- Implement connectivity detection (
navigator.onLine+ custom event) - Implement auto-flush on reconnect
- Integrate with
@bytelyst/telemetry-client(track sync success/failure/conflicts) - Write comprehensive tests (20+ tests):
- Queue persistence across "restarts"
- Retry behavior
- Conflict resolution for each strategy
- Deduplication
- Connectivity changes
- Migrate ChronoMind web to use
@bytelyst/sync(prove it works) - Document API, storage adapters, conflict strategies
Acceptance Criteria:
createSyncEngine()returns a working engine with all methods- Offline queue persists across page reloads (localStorage adapter)
- Conflicts detected and resolved per configured strategy
- ChronoMind web successfully migrated (no regression)
- 20+ tests passing
Estimated effort: 3 days
Dependencies: @bytelyst/api-client (already exists)
Blocks: Phase 3 native SDKs (Swift/Kotlin port)
3. Phase 2 — Developer Experience (Weeks 3–6)
Theme: Tools that eliminate scaffolding and boilerplate for new products.
3.1 CLI Scaffolder (@bytelyst/create-app)
What: Interactive CLI that generates a fully wired product repo from a product manifest.
Location: packages/create-app/
Tasks:
- Create package structure with
bin/create-app.tsentry point - Implement interactive prompts (using
@inquirer/promptsorprompts):- Product name, ID, bundle ID, domain
- Platform selection: Web (Next.js), Expo (React Native), iOS (SwiftUI), Android (Compose)
- Feature selection: Auth, Billing, Telemetry, Feature Flags, Offline Sync, Push Notifications
- User dashboard: Yes/No
- Create template directory structure:
templates/nextjs-web/— Next.js 16 App Router with allsrc/lib/wiringtemplates/expo-rn/— Expo SDK with router, Zustand, MMKVtemplates/swiftui-ios/— SwiftUI scaffold with servicestemplates/compose-android/— Jetpack Compose scaffoldtemplates/agents-md/— AGENTS.md templatetemplates/shared/— .gitignore, .env.example, README.md, CLAUDE.md
- Implement template engine (simple
{{VARIABLE}}replacement + conditional blocks) - Implement
product.jsongeneration from prompts - Implement auto-registration:
- POST to platform-service
/productsto register product - Add containers to
cosmos-init.ts(or via API) - Seed default feature flags
- POST to platform-service
- Implement git init + first commit
- Add
--from product.jsonflag to skip prompts and use existing manifest - Add
--dry-runflag - Write tests for template rendering and manifest generation
- Publish as
npx @bytelyst/create-app
Acceptance Criteria:
- Running
npx @bytelyst/create-appinteractively produces a buildable repo --from product.jsonproduces same result non-interactively- Generated Next.js app starts with
npm run devimmediately - Generated AGENTS.md is complete and accurate
- All
src/lib/wiring files have correct product ID
Estimated effort: 5 days Dependencies: Phase 1 product manifest Blocks: None (but enables faster onboarding)
3.2 Auth UI Kit (@bytelyst/auth-ui)
What: Shared React components for auth flows — login, register, forgot password, email verification, SSO.
Location: packages/auth-ui/
Tasks:
- Create package structure
- Design component API (props interface for each component):
<LoginPage productName logo theme ssoProviders onSuccess /><RegisterPage productName logo theme onSuccess /><ForgotPasswordPage productName logo theme /><ResetPasswordPage productName logo theme /><VerifyEmailPage productName logo theme /><OnboardingShell steps currentStep onNext onBack onComplete />
- Implement
LoginPage:- Email + password form with validation
- "Remember me" checkbox
- SSO buttons (Google, Apple, Microsoft) — configurable
- "Forgot password" link
- "Create account" link
- Loading/error states
- Implement
RegisterPage:- Name, email, password, confirm password
- Terms checkbox
- Password strength indicator
- Implement
ForgotPasswordPage→ResetPasswordPageflow - Implement
VerifyEmailPagewith code input - Implement
OnboardingShell— step indicator, navigation, progress bar - Wire all components to
@bytelyst/auth-clientinternally - Theme support: dark/light, custom accent colors via CSS custom properties
- Responsive design (mobile + desktop)
- Accessibility (ARIA labels, keyboard navigation, screen reader)
- Write tests (component rendering, form validation, submission flow)
- Migrate one existing product's auth pages to use the kit (prove it works)
Acceptance Criteria:
<LoginPage>handles full login flow including error states- Components work with any product's theme
- All forms validate client-side before submission
- Accessible (passes axe-core audit)
- One product successfully migrated
Estimated effort: 5 days
Dependencies: @bytelyst/auth-client (already exists)
Blocks: None
3.3 API Route Generator
What: CLI to generate Next.js App Router API routes from entity definitions.
Location: packages/create-app/src/generators/api-routes.ts (or standalone script)
Tasks:
- Design CLI:
npx @bytelyst/gen:api-route --name tasks --methods GET,POST,PATCH,DELETE - Generate
src/app/api/<name>/route.tswith GET (list) + POST (create) - Generate
src/app/api/<name>/[id]/route.tswith GET (detail) + PATCH + DELETE - Include standard patterns: auth check, Zod validation, error handling, rate limiting
- Support
--with-handlerflag to wrap withapiHandler()HOF - Write tests for generated output
Acceptance Criteria:
- Generated routes pass TypeScript type-check
- Routes include auth, validation, error handling
--with-handlerwraps routes in error handler HOF
Estimated effort: 2 days Dependencies: None Blocks: None
3.4 AGENTS.md Auto-Generator
What: Generate AGENTS.md from product.json + repo scan.
Location: packages/create-app/src/generators/agents-md.ts
Tasks:
- Scan repo directory structure (glob pattern)
- Read
product.jsonfor identity, stack, conventions - Count test files and estimate test count
- List key files per domain (auto-detect from directory names)
- Generate markdown from template with all sections:
- Project identity table
- Repo layout tree
- Tech stack table
- Coding conventions (inherited from ByteLyst + product-specific)
- File ownership map
- Build & test commands
- Common pitfalls
- Output to
AGENTS.md+ symlinks:CLAUDE.md,.cursorrules,.windsurfrules - Add
--updateflag to refresh without overwriting custom sections - Add to
/repo_update-agent-docsworkflow
Acceptance Criteria:
- Generated AGENTS.md matches quality of hand-written ones
--updatepreserves custom sections (marked with<!-- CUSTOM -->fences)- All 4 agent doc files stay in sync
Estimated effort: 2 days Dependencies: Phase 1 product manifest Blocks: None
4. Phase 3 — Native & Declarative (Weeks 7–12)
Theme: Eliminate boilerplate for native apps and backend CRUD entirely.
4.1 Native Swift SDK (ByteLystSDK)
What: A Swift Package providing auth, telemetry, feature flags, and sync for all iOS/macOS/watchOS apps.
Location: New repo: bytelyst-ios-sdk/ (or packages/ios-sdk/ in common-plat)
Tasks:
- Create Swift Package structure with targets:
ByteLystSDK,ByteLystSDKTests - Implement
ByteLystPlatformentry point:let platform = ByteLystPlatform(config: .init( productId: "peakpulse", baseUrl: "https://api.peakpulse.app", authStorage: KeychainTokenStorage() )) - Auth module:
platform.auth.login(email:password:)→AuthResultplatform.auth.register(name:email:password:)→AuthResultplatform.auth.logout()platform.auth.currentUser→User?- Token storage in Keychain
- Silent token refresh
- Telemetry module:
platform.telemetry.track(eventType:module:eventName:tags:metrics:)- Background queue with batching (max 50 events or 30s interval)
- Flush on app background / terminate
- Install ID persistence in UserDefaults
- Session ID rotation on app foreground
- Feature flags module:
platform.flags.isEnabled(key:)→Boolplatform.flags.value(key:)→String?- Background polling (configurable interval, default 5 min)
- Local cache in UserDefaults
- Override support for development
- Sync module:
platform.sync.register(entity:endpoint:conflictStrategy:)platform.sync.push(entity:data:)platform.sync.pull()→SyncResult- Offline queue in UserDefaults (or file-based for large payloads)
- Retry with exponential backoff
- HTTP layer:
- URLSession-based with auth header injection
- Request ID propagation
- Timeout + retry for idempotent requests
- Audit existing Swift code across products:
- ChronoMind:
Shared/Cloud/PlatformSyncManager.swift,Shared/Notifications/ - LysnrAI:
LysnrAI/Services/TelemetryService.swift, auth flow - MindLyst: no iOS SDK yet (uses KMP)
- ChronoMind:
- Write XCTests (30+ tests)
- Migrate ChronoMind iOS to use
ByteLystSDK(prove it works) - Document setup, usage, and migration guide
Acceptance Criteria:
- Single
import ByteLystSDKgives access to auth, telemetry, flags, sync - All modules work offline (queue/cache) and sync when online
- ChronoMind iOS successfully migrated
- 30+ tests passing
- Works on iOS 16+, macOS 14+, watchOS 10+
Estimated effort: 8 days Dependencies: Phase 1 sync engine (for design parity) Blocks: None
4.2 Native Kotlin SDK (com.bytelyst.sdk)
What: Equivalent of the Swift SDK for Android/Wear OS.
Location: New module or repo for Kotlin SDK
Tasks:
- Create Kotlin library module structure
- Implement
ByteLystPlatformentry point (mirror Swift API) - Auth module (OkHttp + kotlinx.serialization)
- Telemetry module (coroutine-based batching)
- Feature flags module (SharedPreferences cache)
- Sync module (offline queue in SharedPreferences or Room)
- HTTP layer (OkHttp interceptor for auth + request ID)
- Audit existing Kotlin code:
- ChronoMind:
app/.../sync/PlatformApiClient.kt,SyncRepository.kt - NomGap:
src/api/client.ts(React Native, different approach)
- ChronoMind:
- Write JUnit5 tests (25+ tests)
- Migrate ChronoMind Android to use SDK
- Document setup and usage
Acceptance Criteria:
- Same API surface as Swift SDK
- Works with Jetpack Compose and traditional Android
- 25+ tests passing
- ChronoMind Android migrated
Estimated effort: 6 days Dependencies: Phase 1 sync engine (for design parity) Blocks: None
4.3 Universal Dashboard Shell (@bytelyst/dashboard-shell)
What: A configurable Next.js layout with built-in pages for profile, billing, settings, notifications.
Location: packages/dashboard-shell/
Tasks:
- Create package structure
- Implement
<DashboardShell>layout component:- Responsive sidebar (collapsible on mobile)
- Top bar with user avatar + dropdown
- Breadcrumbs
- Theme toggle (dark/light)
- Keyboard shortcut support (
Cmd+Ksearch,Cmd+,settings)
- Implement built-in pages:
/profile— view/edit user profile, avatar upload/billing— current plan, Stripe customer portal link, payment history/settings— notification preferences, units, theme, data export/notifications— notification preference toggles
- Configuration via props:
productName,logo,navItems[],features{}- Feature flags:
billing: true/false,profile: true/false, etc.
- Wire to
@bytelyst/auth-clientfor user context - Wire to
@bytelyst/api-clientfor platform-service calls - Theme support via CSS custom properties
- Write tests (component rendering, navigation, responsive behavior)
- Migrate user-dashboard-web to use shell (prove it works)
- Document configuration options
Acceptance Criteria:
<DashboardShell navItems={[...]} features={{ billing: true }}>renders full layout- Built-in pages are functional (not just stubs)
- Responsive on mobile
- user-dashboard-web successfully migrated
Estimated effort: 8 days Dependencies: Phase 1 shared UI components, Phase 2 auth UI kit Blocks: None
4.4 Declarative YAML Backend Modules
What: Define backend CRUD modules as YAML files; runtime generates Fastify routes automatically.
Location: services/platform-service/src/lib/declarative-loader.ts
Tasks:
- Design YAML schema for module definitions:
- Entity name, container, partition key
- Field definitions with types, validation rules, defaults
- Endpoint definitions with method, path, auth requirements
- Custom endpoint stubs (
custom: true)
- Implement YAML parser + Zod schema validator for module definitions
- Implement runtime route generator:
- Read all
.module.yamlfiles from amodules/declarative/directory - Generate Fastify routes at startup (no code generation — runtime interpretation)
- Apply standard patterns: auth, validation, error handling, audit logging
- Support filtering, sorting, pagination for list endpoints
- Read all
- Implement standard CRUD handlers:
- List with filtering + sorting + pagination
- Get by ID
- Create with validation
- Update (partial) with validation
- Delete
- Support custom endpoints (generate handler stubs in a
custom/directory) - Auto-register containers in Cosmos
- Write comprehensive tests (15+ tests)
- Migrate one simple existing module to YAML as proof (e.g.,
changelog) - Document YAML schema and usage
Acceptance Criteria:
- A
.module.yamlfile with no TypeScript produces working CRUD endpoints - Standard CRUD operations work correctly (create, read, update, delete, list)
- Custom endpoints generate stub files for manual implementation
- One existing module successfully migrated
- No performance regression vs hand-written modules
Estimated effort: 8 days Dependencies: Phase 1 module generator (informs schema design) Blocks: None
5. Phase 4 — Polish & Scale (Weeks 13–16)
Theme: Cross-product visibility, zero-touch provisioning, and final polish.
5.1 Auto-Registration on First Request
Tasks:
- Detect unknown
productIdin platform-service request middleware - Auto-create product doc with minimal fields (id, name from header, createdAt)
- Auto-create Cosmos containers listed in product manifest (if provided via config endpoint)
- Auto-seed default feature flags (global defaults)
- Log to audit:
product.auto_registered - Add admin notification on new product registration
- Security: rate limit new registrations, require valid JWT
- Tests (8 tests)
Estimated effort: 3 days Dependencies: Phase 1 product manifest
5.2 Multi-Product Telemetry Dashboard
Tasks:
- Add cross-product query endpoint:
GET /telemetry/cross-product?products=a,b,c - Admin dashboard page: Ops → Cross-Product Telemetry
- Total events/day per product (stacked bar chart)
- Error rates per product (line chart)
- Top error clusters across products
- Feature adoption comparison
- Tests (6 tests)
Estimated effort: 4 days Dependencies: Existing telemetry module
5.3 Shared Onboarding Analytics
Tasks:
- New platform-service module:
modules/onboarding/- Track step completion:
POST /onboarding/step { productId, userId, stepName, stepIndex } - Track completion:
POST /onboarding/complete { productId, userId } - Query funnel:
GET /onboarding/funnel?productId=x→ step-by-step conversion rates
- Track step completion:
- Admin dashboard widget: Onboarding Funnel visualization
- Cosmos container:
onboarding_events(partitioned byproductId) - Tests (8 tests)
Estimated effort: 3 days Dependencies: None
5.4 Pre-Built Stripe Checkout Flow
Tasks:
- New endpoint:
POST /billing/checkout→ creates Stripe Checkout Session- Input:
productId,userId,priceId,successUrl,cancelUrl - Returns:
{ url: "https://checkout.stripe.com/..." }
- Input:
- Client redirect helper in
@bytelyst/api-client - Support trial periods, promo codes, tax
- Tests (6 tests)
Estimated effort: 2 days Dependencies: Existing Stripe module
5.5 Cross-Product User Dashboard
Tasks:
- Investigate: single dashboard showing all products a user has accounts in
- Unified settings page (preferences apply across products)
- Single sign-on across products (shared JWT, product-scoped permissions)
- Design doc + prototype (may be too large for Phase 4)
Estimated effort: 5 days (investigation + design + prototype) Dependencies: Phases 1–3
6. Dependency Graph
product.json (P1.1)
│
├──→ CLI scaffolder (P2.1)
│ ├──→ AGENTS.md auto-gen (P2.4)
│ └──→ API route generator (P2.3)
│
├──→ Auto-registration (P4.1)
│
└──→ Design token generation (existing)
Module generator (P1.2)
│
└──→ Declarative YAML modules (P3.4)
Shared UI components (P1.3)
│
└──→ Dashboard shell (P3.3)
│
└──→ Cross-product dashboard (P4.5)
Sync engine (P1.4)
│
├──→ Swift SDK (P3.1)
└──→ Kotlin SDK (P3.2)
Auth UI kit (P2.2)
│
└──→ Dashboard shell (P3.3)
Telemetry (existing)
│
└──→ Multi-product telemetry (P4.2)
7. Success Metrics
| Metric | Baseline (Now) | After Phase 1-2 | After Phase 3-4 | Target |
|---|---|---|---|---|
Time to first npm run dev |
3–4 hours | 15 minutes | 5 minutes | < 10 min |
| Time to deployed MVP | 3–5 days | 1–2 days | 4–8 hours | < 8 hours |
| Lines of code per new product | ~3,000 | ~1,500 | ~500 | < 500 |
| Backend modules (manual code) | 150–250 lines each | 0 lines (generated) | 0 lines (YAML) | 0 lines |
| Native SDK integration | ~400 lines per platform | ~400 lines | ~20 lines | < 20 lines |
| Repeated files across products | ~15 files | ~5 files | ~0 files | 0 |
| Test coverage of platform | 1,141 tests | 1,300+ | 1,500+ | > 1,500 |
8. Risk Register
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Over-abstraction makes platform hard to understand | High | Medium | Keep escape hatches; any generated code can be hand-modified |
| YAML declarative modules too limited for complex logic | Medium | Medium | Hybrid approach: YAML for CRUD, hand-written for complex modules |
| Native SDKs diverge from web package API | Medium | Low | Shared API design doc; test parity |
| CLI scaffolder templates go stale | High | High | Auto-test: CI runs scaffolder and builds result weekly |
| Manifest schema changes break existing products | High | Medium | Versioned schema with migration guide |
| Performance overhead of runtime YAML interpretation | Low | Low | Benchmark; fall back to code generation if needed |
| Too many packages to maintain | Medium | Medium | Regular dependency audit; merge underused packages |
Appendix: Quick Reference
All New Packages (by phase)
| Phase | Package | Type |
|---|---|---|
| 1 | Product manifest (in @bytelyst/config) |
Extension |
| 1 | @bytelyst/dashboard-components |
New package |
| 1 | @bytelyst/sync |
New package |
| 1 | Module generator (in platform-service) | Script |
| 2 | @bytelyst/create-app |
New package (CLI) |
| 2 | @bytelyst/auth-ui |
New package |
| 2 | API route generator (in create-app) | Script |
| 2 | AGENTS.md generator (in create-app) | Script |
| 3 | ByteLystSDK (Swift) |
New repo/package |
| 3 | com.bytelyst.sdk (Kotlin) |
New repo/package |
| 3 | @bytelyst/dashboard-shell |
New package |
| 3 | Declarative module loader (in platform-service) | Runtime |
Total Estimated Effort
| Phase | Duration | Effort |
|---|---|---|
| Phase 1 | Weeks 1–2 | 9 days |
| Phase 2 | Weeks 3–6 | 14 days |
| Phase 3 | Weeks 7–12 | 30 days |
| Phase 4 | Weeks 13–16 | 17 days |
| Total | 16 weeks | 70 days |