System Overview
NearSync is a single-codebase, manifest-driven multi-tenant SaaS platform built on a Turborepo monorepo. Three user-facing applications and a set of shared internal packages share a unified backend powered by Supabase (PostgreSQL, Auth, Storage, Edge Functions, Realtime).
The system supports two operational models:
- Managed: Clients share a NearSync-hosted Supabase instance, isolated by
org_idand row-level security (RLS). - BYOK (Bring Your Own Keys): Clients deploy the same application code against their own Supabase project.
Zero code forks. Customization is entirely runtime-driven via the SystemManifest -- a JSON document stored in the database that controls module availability, feature flags, branding, security policies, and operational limits.
High-Level Topology
+-------------------------------------------------------------------+
| Internet |
+-------------------------------+-----------------------------------+
|
+--------------------+--------------------+
| | |
v v v
admin.nearsync.tech portal.nearsync.tech nearsync.tech
| | |
v v v
+-------------------------------------------------------------------+
| Vercel Deployment (Git-driven, no GitHub Actions) |
+-------------------------------------------------------------------+
| admin-dashboard client-portal marketing-website |
| (React + Vite) (React + Vite) (React + Vite) |
+-------------------------------+-----------------------------------+
| All share
| shared packages
v
+-------------------------------------------------------------------+
| Turborepo Workspace |
+-------------------------------------------------------------------+
| @nearsync/types |
| @nearsync/supabase-client @nearsync/ai-service |
| @nearsync/theme-engine @nearsync/state-store |
| @nearsync/shared-logic @nearsync/ui-system |
| @nearsync/comms-service @nearsync/import-engine |
| @nearsync/eslint-config @nearsync/tsconfig |
+-------------------------------+-----------------------------------+
|
v
+-------------------------------------------------------------------+
| Supabase (Auth, DB, Storage, Realtime) |
+-------------------------------------------------------------------+
| PostgreSQL Auth Storage Edge Functions Realtime Channels |
| org_id multi-tenancy (Managed) |
| RLS on tenant-scoped tables |
+-------------------------------------------------------------------+
| | |
v v v
hyper-worker standalone External APIs
(services) edge functions (Google, Stripe, Twilio,
Gemini, Canva, HubSpot...)
Beyond the three Vercel-hosted SPAs, the backend runs on Supabase edge functions (the hyper-worker gateway plus standalone OAuth and cron functions). NearSync also exposes a public API and MCP server at api.nearsync.tech -- proxied through a small Vercel edge project -- and developer documentation at docs.nearsync.ai.
Deployment Boundary
All application code (frontend and edge functions) is deployed together from a single Git repository via Vercel Git integration. No GitHub Actions orchestration -- Vercel's CI/CD pipeline handles builds, test execution, and rollouts.
Branch strategy:
main-- productionstage-- staging preview environment
Intelligent builds: Each Vercel project uses npx turbo-ignore to skip rebuilding unaffected applications when only one package changes.
Application Layer
Three React + Vite single-page applications serve distinct user personas.
1. Admin Dashboard (admin.nearsync.tech)
Purpose: Internal operations platform for NearSync HQ and enterprise admin users.
Package: @nearsync/admin-dashboard
Auth requirement: JWT from Supabase; must have admin or operator role.
Lazy-Loaded Modules:
| # | Module | Description |
|---|---|---|
| 1 | Intelligence | Analytics dashboard, system health |
| 2 | Dashboards | Custom dashboard builder (white-label components) |
| 3 | Comms | WhatsApp, Email, Voice (via Twilio) |
| 4 | Sales | CRM, leads, pipeline, forecast |
| 5 | Marketing | Campaign management, email sequences |
| 6 | Website | Landing page builder, SEO, analytics |
| 7 | Projects | Project tracking, sprints, backlog |
| 8 | Operations | Resource allocation, capacity planning |
| 9 | Support | Ticketing, knowledge base, customer feedback |
| 10 | People | HRMS, org chart, payroll, attendance |
| 11 | Finance | Invoicing, expense tracking, payment reconciliation |
| 12 | System | User management, roles, audit logs, Sentinel monitoring |
| 13 | Bookmarks | Quick links, saved searches |
| 14 | User Settings | Profile, preferences, MFA |
Each module is code-split and loaded on-demand via React.lazy() + Suspense. Module availability is gated by the ModuleGuard component, which checks the SystemManifest.
2. Client Portal (portal.nearsync.tech)
Purpose: Client-facing self-service platform.
Package: @nearsync/client-portal
Auth requirement: JWT from Supabase; must have client role.
Tab Structure:
| Tab | Day-1 Access | Gated Behind | Purpose |
|---|---|---|---|
| Overview | Yes | -- | Dashboard, recent activity, quick stats |
| Brand Kit | Yes | -- | Logo, colors, fonts, guidelines |
| Design Studio | Yes | -- | Website builder, visual identity setup |
| Discuss | Yes | -- | Chat with NearSync team |
| Help | Yes | -- | FAQ, documentation, ticket creation |
| Financials | portal_onboarded | Invoices, payments, billing history | |
| Docs | portal_onboarded | Document repository, contracts | |
| Tech | portal_onboarded | API keys, webhooks, setup guides (BYOK only) |
The portal_onboarded flag is set by the NearSync team after the onboarding call.
Design Studio Scope (Launch):
- Identity tab only: primary color, surface color, text color, logo (light + dark variants), favicon URL, site title
- Writes to
project_brandtable - Changes synced to the client portal UI in real time via Realtime channels
3. Marketing Website (nearsync.tech)
Purpose: Public landing site, auth gateway, documentation.
Package: @nearsync/marketing-website
Auth requirement: Optional (public pages); required for login/signup.
Pages: Pricing, features, use cases, integrations, help and support hub, login/signup gateway, and a solutions grid showcasing the platform's modules.
Package Architecture
Shared internal packages in packages/ provide common functionality across all three applications.
Critical rule: No cross-imports between apps/. All shared code lives in packages.
Dependency Graph
+----------------------+
| @nearsync/types |
| (pure types, 0 deps)|
+----------+-----------+
|
+-------------------------+--------------------+-----------+
| | |
v v v
+----------------------------+ +----------------------+ Others
| @nearsync/ | | Feature packages |
| supabase-client | | (lower coupling) |
| | | |
| - AuthProvider | +-----| - ai-service |
| - useAuth() | | | - theme-engine |
| - DB hooks | | | - state-store |
| - useSystemManifest() | | | - shared-logic |
| - Service layer base | | | - comms-service |
+----------+---------------+ | | - import-engine |
| | +----------------------+
| |
+--------------------+----------------+
| |
v v
+------------------------------+
| @nearsync/ui-system |
| |
| - Shadcn/Radix wrappers |
| - Dashboard widgets |
| - Modals, forms, tables |
| - App-agnostic components |
+----------+-------------------+
|
+--------------------------+------------------------+
| | |
v v v
+------------------+ +------------------+ +--------------------+
| admin-dashboard | | client-portal | | marketing-website |
| | | | | |
| HQ modules | | Portal tabs | | Marketing pages |
| HQ operations | | Branded portal | | Auth gateway |
+------------------+ +------------------+ +--------------------+
Package Inventory
| Package | Status | Purpose |
|---|---|---|
@nearsync/types | Functional | Pure TypeScript types; zero runtime dependencies. Includes SystemManifest, FeatureFlags, and auto-generated database types. |
@nearsync/supabase-client | Functional | Supabase client wrapper; AuthProvider context; useAuth hook (session, user, profile, permissions, manifest); database query builders; service layer base class. |
@nearsync/ai-service | Functional | Multi-provider AI routing (8 providers: Gemini, OpenAI, Anthropic, Grok, Mistral, Groq, DeepSeek, Ollama); config caching for model metadata; client and server-side implementations. |
@nearsync/theme-engine | Functional | CSS variable system (--app-surface, --app-background, --app-border, --accent-color); ThemeProvider context; dark mode toggle; brand color injection from SystemManifest. |
@nearsync/state-store | Functional | Zustand stores for global state (modals, notifications, UI state); persisted to localStorage where applicable. |
@nearsync/shared-logic | Functional | Utility functions, formatters, validators, i18n strings; no UI dependencies. |
@nearsync/ui-system | Functional | Shadcn/Radix-based components; dashboard widgets (metric cards, charts); modals, forms, tables; designed for reuse across all three apps. |
@nearsync/comms-service | Functional | Wrapper for Twilio voice, WhatsApp messaging, and email. |
@nearsync/import-engine | Functional | CSV/XLSX parsing, AI-powered column mapping, batch import logic, 4-step wizard UI. |
@nearsync/eslint-config | Config | Shared ESLint rules across workspace. |
@nearsync/tsconfig | Config | Shared TypeScript config. |
Authentication and Session Management
Authentication Provider: Supabase Auth
All three applications delegate identity to Supabase's auth system, which uses PostgreSQL row-level security (RLS) to enforce multi-tenant isolation.
User --> Login/Signup Form
|
v
Supabase Auth
- Password verification (bcrypt)
- Email verification (OTP)
- OAuth (Google, GitHub, Microsoft, etc.)
|
v
JWT issued (access_token + refresh_token)
- JWT payload contains: user_id, email, custom claims
- TTL: 3600 seconds (refreshed via refresh_token)
|
v
Client stores JWT in cookie (cross-domain) or localStorage
|
v
AuthProvider wraps app tree
- Initializes Supabase client
- Fetches profile from `profiles` table
- Subscribes to `role_permissions` realtime channel
- Loads SystemManifest via useSystemManifest()
|
v
useAuth() hook provides:
{
session, // Supabase session
user, // Supabase user object
profile, // Profile record (org_id, name, avatar...)
manifest, // Full config for this org
permissions, // Role-based permissions (realtime subscribed)
isModuleEnabled(id), // boolean
isFeatureEnabled(flag), // boolean
checkPermission(key), // boolean
mfaEnabled, // TOTP enrollment status
signUp(),
signIn(),
signOut(),
}
Cross-Domain Session Storage
On production domains (admin.nearsync.tech, portal.nearsync.tech, nearsync.tech), the JWT is stored in a chunked cookie with domain=.nearsync.tech. Supabase cookies are split into 3500-byte chunks, so large JWTs span multiple cookies. When a user navigates between subdomains, the browser automatically includes the cookies and the session persists without re-login.
MFA (Multi-Factor Authentication)
TOTP enrollment via Supabase MFA API:
- User requests MFA enrollment.
- Supabase generates a QR code (TOTP secret).
- User scans with an authenticator app.
- User enters a 6-digit code.
- If valid, MFA is enabled on the profile.
- Future logins require TOTP verification.
SystemManifest Pipeline
The SystemManifest is the single source of truth for what each organization can see and do. It is a JSON document stored in the global_settings table and cached in-memory on the client.
Structure
SystemManifest {
instance: {
id: string, // org_id
tier: 'starter' | 'standard' | 'standard_plus' | 'advanced' | 'custom',
deployment: 'managed' | 'byok',
vertical: 'healthcare' | 'retail' | 'professional_services' | 'fintech' | 'custom',
region: 'us-east' | 'eu-west' | 'ap-south',
trial: boolean,
trial_expires_at: ISO8601,
},
modules: {
[moduleId]: {
enabled: boolean,
tier_required: 'starter' | 'standard' | 'standard_plus' | 'advanced',
feature_overrides: string[],
}
// 14 module IDs: intelligence, dashboards, comms, sales, marketing, website,
// projects, operations, support, people, finance, system,
// bookmarks, user_settings
},
features: {
[featureFlagId]: boolean,
// 60+ flags: ai_chat_enabled, sms_campaigns_enabled,
// inventory_sync_enabled, etc.
},
security: {
mfa_required: boolean,
session_timeout_minutes: number,
ip_whitelist: string[], // CIDR blocks
password_policy: {
min_length: number,
require_uppercase: boolean,
require_symbols: boolean,
},
enforce_saml: boolean,
saml_provider_url: string,
},
branding: {
company_name: string,
logo_url: string,
favicon_url: string,
primary_color: hex,
surface_color: hex,
text_color: hex,
support_email: string,
support_phone: string,
},
integrations: {
whatsapp: { enabled: boolean, account_id: string },
twilio: { enabled: boolean, phone_numbers: string[] },
gemini: { enabled: boolean, default_model: string },
openai: { enabled: boolean, default_model: string },
stripe: { enabled: boolean },
razorpay: { enabled: boolean },
// ... additional integrations
},
limits: {
max_users: number,
storage_gb: number,
ai_tokens_per_month: number,
crm_contacts_limit: number | null, // null = unlimited
},
operations: {
timezone: string, // IANA timezone
currency: string, // ISO 4217
date_format: string,
work_days: string[],
work_hours_start: string,
work_hours_end: string,
},
}
Note: API keys are never stored in the manifest. Integration credentials are fetched at runtime from an encrypted table and are never bundled in client code.
Manifest Lifecycle
- Load: When the
AuthProvidermounts, theuseSystemManifest()hook checks localStorage for a cached copy. On cache miss, it fetches from theglobal_settingstable and merges with safe defaults. - Subscribe: The hook subscribes to the
global_settingsRealtime channel. Any INSERT, UPDATE, or DELETE event triggers a re-fetch plus a localStorage update. - Consume: Components use
isModuleEnabled(),isFeatureEnabled(), andcheckPermission()to gate UI. Branding values are injected as CSS variables by the ThemeProvider.
Module Gating
<ModuleGuard moduleId="crm">
<SalesHQ />
</ModuleGuard>
ModuleGuardcallsisModuleEnabled()on the manifest.- If
false, the guard renders an upsell message instead of the module. - If
true, the child component renders normally.
Feature Flags
Fine-grained boolean flags in manifest.features control subsystems:
if (manifest.features.ai_chat_enabled) {
return <AIChat />;
}
Feature flags are per-org and can be overridden individually.
Multi-Tenancy Model
Managed (Shared Supabase Instance)
All managed clients share a single Supabase project. Isolation is enforced via the org_id column and row-level security.
Client User Logs In
|
v
Supabase Auth
- User created in auth.users table
- JWT issued with user_id claim
|
v
Profile Lookup (profiles table)
WHERE id = <user_id>
--> Resolves org_id, role, name, avatar
|
v
Every Query Scoped by org_id
RLS Policy (RESTRICTIVE):
CREATE POLICY "tenant_isolation" ON crm_contacts
AS RESTRICTIVE
FOR ALL
USING (
org_id = (
SELECT org_id FROM profiles
WHERE id = auth.uid()
)
);
RLS enforcement: Every tenant table has a RESTRICTIVE policy. Multiple policies are AND'ed together -- even if a permissive policy grants access, the org_id check still applies. This guarantees no data leaks between organizations.
Tables with org_id isolation span these logical domains: Core, CRM, Finance, HRMS, Support, Comms, Projects, Workflows, Bookings, Assets, Knowledge Base, Custom Fields, Marketing, Design and Branding, Integrations, and Admin.
BYOK (Bring Your Own Keys)
BYOK clients deploy the same application code but point to their own Supabase project via environment variables.
Key differences from the managed model:
- No org_id needed -- single-tenant; the entire database belongs to the client.
- Schema still deployed -- all tables with all migrations.
- RLS still active -- enforces role-based access rather than org-based isolation (e.g., user role vs admin role).
- Data sovereignty -- the client owns the entire database, backups, and encryption keys.
- Monitoring -- Sentinel (metadata-only) monitors heartbeat and basic stats with no row-level visibility into client data.
Backend Architecture: Supabase + Hyper-Worker
Supabase: PostgreSQL at the Core
- Database: tenant-scoped tables across its logical domains (CRM, Finance, HRMS, Comms, Projects, Support, Workflows, Bookings, Assets, KB, Integrations, Audit, Custom Fields, Admin).
- Auto-Generated Types: Full TypeScript types are regenerated from the schema, providing 100% type-safe DB queries via the Supabase JS client.
- Storage Buckets: Files (contracts, invoices, PDFs, uploaded documents) are accessed via signed URLs.
- Realtime Channels: Used for manifest changes, RBAC updates, chat delivery, and org-scoped entity updates.
Hyper-Worker Edge Function
A single entry point (POST /functions/v1/hyper-worker) routes all backend business logic requests to appropriate service handlers.
Request flow:
- CORS check -- origin-locked to production domains.
- Auth middleware -- JWT validation. Public endpoints (webhooks, signup, login) skip auth.
- Rate limiter -- per-IP per-endpoint, in-memory. Returns HTTP 429 if exceeded.
- Route switch --
body.typedispatches to the correct service method.
15 Service Modules:
| # | Service | Responsibility |
|---|---|---|
| 1 | AuthService | Signup, login, invites, welcome email, password reset, MFA enrollment |
| 2 | AdminService | Admin-only actions (session management, system health) |
| 3 | WhatsAppService | Send/receive messages, media upload, webhook handling |
| 4 | TwilioService | Voice call tokens, call status webhooks, recording retrieval |
| 5 | GoogleWorkspaceService | Gmail API, Calendar API, Meet join link generation |
| 6 | GoogleDocsEngine | Clone template docs, inject data, export to PDF |
| 7 | BookingService | Availability calculation, booking creation, calendar sync, reminders |
| 8 | FinanceService | Payment processing, webhook handling, reconciliation |
| 9 | LegalService | Document signing, contract templates, signature collection |
| 10 | ProjectService | Project creation, AI-powered PRD generation, client import enrichment |
| 11 | ReviewsService | Google Places API integration, review fetch, sentiment analysis |
| 12 | WorkflowExecutorService | Visual workflow engine, node execution, approvals, AI nodes |
| 13 | AIService | Multi-provider chat routing, token management, streaming |
| 14 | CrmSyncService | HubSpot/Salesforce OAuth, contact/deal sync, field mapping |
| 15 | IntegrationsService | 14+ OAuth providers, token refresh, permission checking |
Standalone Edge Functions
Six additional edge functions handle async, scheduled, and OAuth tasks:
- canva-oauth -- Canva design OAuth callback, proxy Canva API calls
- crm-oauth -- HubSpot/Salesforce OAuth callback, token exchange
- integration-oauth -- Unified OAuth callback router (14+ providers)
- process-reminders -- Cron-triggered; sends booking and task reminders
- fetch-reviews -- Cron-triggered; syncs Google Places reviews
- lusha-sync -- Cron-triggered; enriches leads with Lusha data
Data Layer
Database Schema: Multi-Domain Tables
| Domain | Examples |
|---|---|
| Core | organizations, profiles, global_settings, audit_logs |
| CRM | crm_contacts, crm_companies, crm_pipelines, crm_stages |
| Finance | finance_invoices, finance_company_expenses, finance_payments |
| HRMS | hrms_employees, hrms_attendance, hrms_payroll, hrms_benefits |
| Support | support_tickets, support_attachments, support_sla_rules |
| Comms | chat_messages, notifications, email_logs, whatsapp_messages |
| Projects | projects, project_sprints, project_tasks, project_media |
| Workflows | workflow_definitions, workflow_executions, workflow_approval_requests |
| Bookings | bookings, booking_links, booking_time_slots, booking_reminders |
| Assets | assets, asset_categories, asset_allocations, asset_maintenance |
| Knowledge Base | kb_articles, kb_categories, kb_search_logs |
| Custom Fields | custom_field_definitions, project_custom_fields |
| Marketing | marketing_campaigns, marketing_email_sequences, marketing_analytics |
| Design and Branding | project_brand, design_templates, design_assets |
| Integrations | integration_configs, integration_credentials, oauth_states |
| Admin | role_definitions, role_permissions, permission_groups |
All tenant tables include an org_id column with a RESTRICTIVE RLS policy.
Auto-Generated Types
Database types are regenerated from the Supabase schema and provide exact table/column types, enum types, and Row/Insert types per table. The Supabase JS client uses these for fully type-safe queries.
Schema Management
Migrations follow a timestamp-ordered flow:
- Engineer creates a migration file (
supabase/migrations/<timestamp>_<name>.sql). - Runs locally via
supabase migration up. - Tests in local environment.
- Commits to Git.
- On merge to
main, the Supabase CLI applies migrations during deployment. - For BYOK provisioning, all migrations are replayed against the client's Supabase project.
Security Architecture
NearSync's security model is layered:
| Layer | Mechanism | Scope |
|---|---|---|
| 1 | CORS | Cross-origin requests locked to production domains |
| 2 | JWT Authentication | All non-public endpoints require a valid Supabase JWT |
| 3 | Row-Level Security | Tenant-scoped tables enforce organization isolation via RESTRICTIVE policies |
| 4 | Rate Limiting | Per-IP per-endpoint limits on the hyper-worker edge function |
| 5 | RBAC | Permissions defined in role_permissions table, checked at runtime, realtime-subscribed |
| 6 | API Key Isolation | Sensitive keys stored encrypted at rest, never bundled in client code |
| 7 | BYOK Key Handling | Service role key used once during provisioning, then discarded -- never persisted |
| 8 | Error Monitoring | Sentry integration across all three apps; edge function logging; immutable audit logs |
RLS in Practice
-- Example: CRM Contacts
CREATE POLICY "tenant_isolation" ON crm_contacts
AS RESTRICTIVE
FOR ALL
USING (
org_id = (SELECT org_id FROM profiles WHERE id = auth.uid())
);
RESTRICTIVE policies are evaluated first and AND with any permissive policies. A user cannot see, update, or delete rows belonging to another organization.
RBAC
Permissions are defined in the role_permissions table and checked at runtime:
if (!auth.checkPermission('finance:export_data')) {
return <div>You do not have permission to export data.</div>;
}
Permissions are realtime-subscribed, so RBAC changes take effect immediately without a page refresh.
AI Integration: Multi-Provider Architecture
NearSync integrates with 8 AI providers, automatically routing requests based on model name.
Supported Providers
| Provider | Features |
|---|---|
| Google Gemini | Streaming, vision, function calling |
| OpenAI | Streaming, vision, function calling |
| Anthropic (Claude) | Streaming, vision |
| Grok | Streaming |
| Mistral | Function calling |
| Groq | Streaming |
| DeepSeek | Streaming |
| Ollama (self-hosted) | Streaming |
Routing Flow
- The client specifies a
modelname (e.g.,gemini-pro). - The AI router looks up the provider in the catalog.
- The router sends the request to the hyper-worker with the model name.
- The hyper-worker fetches the API key from the
integration_configstable (org-scoped, encrypted). - The hyper-worker routes to the appropriate provider API.
- The response is streamed back to the client.
Configuration
AI providers are configured per-org via the SystemManifest:
manifest.integrations.gemini = {
enabled: true,
default_model: 'gemini-pro',
};
Per-module overrides are supported (e.g., one module can be locked to a specific model while others use the org default).
Custom Fields Engine
The custom fields engine allows each organization to extend any entity with additional fields, eliminating the need for industry-specific code forks.
How it works:
- Definitions are stored in the
custom_field_definitionstable, scoped byorg_idandentity_type(e.g.,crm_contact,invoice,employee). - Field types supported: text, number, select, multi-select, date, boolean, URL, email, phone, currency.
- Values are stored in entity-specific tables (e.g.,
crm_contact_custom_fields,invoice_custom_fields). - Rendering is automatic: the UI iterates over field definitions and renders the appropriate input component for each.
A healthcare client adds fields like medical_license_number and insurance_provider. A retail client adds product_sku and inventory_location. Same application code; different custom field definitions.
Workflow Engine
The visual workflow engine enables non-technical users to build automations using a node-based editor.
Node types:
| Node Type | Purpose |
|---|---|
| Trigger | Event-based (contact_created, invoice_paid, deal_won) or time-based |
| Condition | Branching logic (field comparisons, boolean checks) |
| Action | Effects: send WhatsApp, send email, create record, update record, call webhook |
| Approval | Pause execution, wait for human decision (approve/reject) |
| Wait | Delay until a specified time; execution paused in DB, resumed by cron |
| AI (Pippin) | AI summarization, classification, or extraction; result stored in workflow variable |
| Output | Mark execution as success, log to audit trail |
Execution model:
- State is persisted to the
workflow_executionstable. - Paused executions (approvals, waits) are stored with
resumed_atas NULL; a cron job processes resumes. - Full audit trail in
workflow_audit_logs(immutable, append-only).
External Service Dependencies
Critical Path
| Service | Purpose | Fallback |
|---|---|---|
| Supabase | Database, Auth, Storage, Realtime, Edge Functions | Managed disaster recovery |
| Resend | All transactional emails | Fallback to SMTP (manual config) |
Feature-Specific
| Service | Purpose | Fallback |
|---|---|---|
| Google Workspace (Gmail, Calendar, Docs, Drive) | Email sync, calendar, document generation | Manual uploads |
| Facebook Graph API | WhatsApp messaging | Form-based replies |
| Stripe | Non-INR payments | Manual invoicing |
| Razorpay | INR payments | Stripe (if available in region) |
| Twilio | Voice calls, SMS | Email-only |
| Google Gemini | AI features, PRD generation, column mapping | Fallback to OpenAI |
| OpenAI | AI chat (alternative to Gemini) | Gemini (if available) |
| Canva API | Design management, template library | Manual uploads |
| HubSpot / Salesforce | CRM sync, deal tracking | Manual CSV import |
| Lusha | Lead enrichment, data append | Skip enrichment |
| Google Places | Review management, sentiment analysis | Skip reviews |
Conventions and Patterns
Import Rules
No cross-imports between apps. All shared code must live in packages:
// Not allowed
import { DashboardCard } from '../../../apps/admin-dashboard/src/components';
// Correct
import { DashboardCard } from '@nearsync/ui-system';
CSS Theming
All colors are set via CSS variables managed by the ThemeProvider, which reads branding values from the SystemManifest:
background-color: var(--app-surface);
border: 1px solid var(--app-border);
color: var(--accent-color);
Feature Gating
// Module gating
<ModuleGuard moduleId="crm">
<CRM />
</ModuleGuard>
// Feature flag
{manifest.features.ai_chat_enabled && <AIChat />}
// Permission check
{auth.checkPermission('finance:export_data') && <ExportButton />}
Database Queries
Type-safe queries via the Supabase JS client:
const { data, error } = await supabase
.from('crm_contacts')
.select('id, name, email')
.order('created_at', { ascending: false });
// RLS automatically scopes results by org_id