Conversation engine
As of now, the frontend team manages one active product, SMS under Pindo.io, with a second service, Pindo.ai, currently in developmentβand more coming soon.
As the Lead Frontend Engineer, my responsibility is to ensure that the frontend architecture scales efficiently as we continue to expand into a multi-service platform.
β Strategic Moves So Far
-
Migration to Next.js App Router
We moved from a traditional React.js setup to Next.js with the App Router, unlocking server components, layout nesting, route groups, and improved routing flexibility. -
Styling: From styled-components to Tailwind CSS
We adopted Tailwind CSS to boost DX and UI consistency while eliminating runtime CSS parsing. -
Rethinking Monorepo
Initially, we explored monorepo architecture to manage services independently. However, due to the tight coupling of services under one user domain (a single Pindo organization), this was reconsidered. The services behave more like modules of one unified platform, not standalone products.
π§ Product Philosophy
-
All services are under one Pindo umbrella.
-
A user must belong to a Pindo organization to access any service.
-
Services are modularβusers can opt-in or out depending on their needs.
-
Based on this, we decided to keep all services in a single Next.js application, leveraging the App Router's modular routing.
ποΈ Proposed Folder Structure
Here's the updated app structure for clarity:
src/
βββ app/
β βββ layout.tsx # Root layout
β βββ page.tsx # Root landing page
β βββ sms/ # Service 1
β β βββ page.tsx
β β βββ layout.tsx
β β βββ components/
β βββ ai/ # Service 2 (e.g., Pindo.ai)
β β βββ page.tsx
β β βββ components/
β βββ telephony/ # Service 3
β βββ settings/ # Org-wide settings
βββ shared-ui/ # Common UI components
βββ shared-utils/ # Reusable helpers and utilities
βββ middleware.ts # Route protection via feature flags
βββ lib/ # API clients, auth utils, etc.
π₯ Dynamic Feature Access via Feature Flags
We will use feature flags (e.g., via @vercel/flags) to:
-
Dynamically show/hide pages and components
-
Restrict access to service routes (e.g.,
/telephony) based on user permissions -
Inject flags at the middleware level using secure server-side checks based on the JWT/session
This keeps unauthorized users from accessing features they arenβt subscribed to, both visually and programmatically.
π App Layout Representation
[Pindo Platform]
|
βββ Home (/) βββΆ Shared Dashboard
βββ /sms βββββββΆ SMS Service
βββ /ai ββββββββΆ AI Assistant (Pindo.ai)
βββ /telephony βββΆ Telephony Service
βββ /settings βββΆ Org/User Settings
βββ Middleware β Checks Auth + Feature Flags
π High-Level Architecture
+---------------------------+
| Browser |
+------------+--------------+
|
v
+---------------------------+
| Next.js Frontend |
| - App Router |
| - TailwindCSS |
| - Middleware (flags) |
| - Modular Services |
+------------+--------------+
|
v
+---------------------------+
| API Layer |
| - Auth (JWT/session) |
| - User Profile |
| - Feature Flags |
| - Service Data |
+------------+--------------+
|
v
+---------------------------+
| Backend |
| - Auth DB |
| - Services Logic |
| - Feature Control |
| - Billing |
+---------------------------+
π High-Level Diagram: Frontend Folder Structure
src/
βββ app/ # Next.js App Router base
β βββ layout.tsx # Root layout
β βββ page.tsx # Root homepage/dashboard
β β
β βββ sms/ # Service 1: SMS
β β βββ page.tsx
β β βββ layout.tsx
β β βββ components/
β β
β βββ ai/ # Service 2: AI Assistant (Pindo.ai)
β β βββ page.tsx
β β βββ components/
β β
β βββ telephony/ # Service 3: Telephony
β β βββ page.tsx
β β βββ components/
β β
β βββ settings/ # Org/user-wide settings
β βββ page.tsx
β
βββ shared-ui/ # Common UI components across all services
βββ shared-utils/ # Shared utility functions
βββ lib/ # Auth, API clients, constants, helpers
βββ middleware.ts # Route protection + dynamic flag checking
βββ types/ # Global TypeScript types/interfaces
β οΈ Notes & Considerations
-
Scalability: Keeping services in one app but isolated by folders and flags allows faster onboarding, testing, and deployments.
-
Security: Feature flags must be enforced both client-side (UX) and server-side (middleware + backend authorization).
-
Performance: Ensure only the needed service code is loaded (optimize with dynamic imports or route groups).
