Skip to content

CodevitsLabs/GetconnectX-FE

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

121 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ConnectX Boilerplate

Expo Router boilerplate organized with a feature-based, vertical-slice architecture.

Why This Pattern

The project is structured so each feature owns its UI, hooks, services, and types in one place. That keeps routes thin, makes features easier to delete or move, and gives new engineers a clear place to start.

Folder Structure

app/                         # Expo Router files only
  (auth)/                    # route wrappers for auth flows
  (tabs)/                    # authenticated shell route wrappers
  _layout.tsx                # app providers + root stack
  index.tsx                  # redirect only
  modal.tsx                  # imports one feature screen

src/
  features/                  # vertical slices
    auth/
    home/
    matches/
    products/
    chat/
    team/
    profile/
    design-system/
  shared/                    # reusable cross-feature code
    components/              # design-system primitives
    hooks/                   # generic hooks
    services/api/            # shared fetch + react-query helpers
    theme/                   # shared tokens and navigation theme
    utils/                   # generic helpers

Golden Rules

  1. app/ should only compose route wrappers and import from feature barrels.
  2. Features expose a public API through index.ts and hide internal details.
  3. Shared code must stay feature-agnostic.
  4. Cross-feature data fetching goes through the shared API layer, then feature hooks.
  5. If a feature can be deleted by removing one folder, the structure is healthy.

Public Import Style

Use feature barrels:

import { LoginScreen } from '@features/auth';
import { ProductsScreen } from '@features/products';

Use shared primitives through shared entry points:

import { AppCard, AppText } from '@shared/components';
import { apiFetch, createApiQueryOptions } from '@shared/services/api';

Avoid deep imports from another feature's internal files.

Current Aliases

Defined in tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./*"],
      "@features/*": ["src/features/*"],
      "@shared/*": ["src/shared/*"]
    }
  }
}

Data Fetching Pattern

The shared API layer lives in src/shared/services/api.

  • apiFetch<T>() handles requests and authorization headers.
  • createApiQueryOptions() gives a consistent base for React Query.
  • Feature services define endpoint-specific functions.
  • Feature hooks call useQuery / useMutation.
  • Feature screens render state.

Example flow from the Products feature:

// src/features/products/services/products-service.ts
export async function fetchProducts() {
  return apiFetch<ProductsResponse>('https://dummyjson.com/products');
}
// src/features/products/hooks/use-products.ts
export function useProducts() {
  return useQuery({
    ...createApiQueryOptions<ProductsResponse>(['products'], 'https://dummyjson.com/products'),
    queryFn: fetchProducts,
  });
}
// app/(tabs)/products.tsx
import { ProductsScreen } from '@features/products';

export default function ProductsRoute() {
  return <ProductsScreen />;
}

Products Demo Feature

For presentation purposes, the app now includes a Products tab that fetches:

  • https://dummyjson.com/products

The response is rendered through the current design pattern:

Running The App

  1. Install dependencies
npm install
  1. Set the required environment variables
EXPO_PUBLIC_API_BASE_URL=...
EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID=...
EXPO_PUBLIC_GOOGLE_IOS_URL_SCHEME=...
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID=...
EXPO_PUBLIC_MOCK_MATCHES_LIST_RESPONSE=success
EXPO_PUBLIC_MOCK_DISCOVERY_REWIND_RESPONSE=off
EXPO_PUBLIC_MOCK_SUPERLIKE_NO_BOOST=false
EXPO_PUBLIC_MOCK_SPOTLIGHT_ACTIVATION_RESPONSE=off
EXPO_PUBLIC_REVENUECAT_ENABLED=false
EXPO_PUBLIC_REVENUECAT_ANDROID_API_KEY=goog_...
EXPO_PUBLIC_REVENUECAT_IOS_API_KEY=appl_...
EXPO_PUBLIC_REVENUECAT_DISCOVERY_BOOSTS_OFFERING_ID=discovery_boosts
EXPO_PUBLIC_REVENUECAT_DISCOVERY_SPOTLIGHT_OFFERING_ID=discovery_spotlight
EXPO_PUBLIC_SUPABASE_ANON_KEY=...
EXPO_PUBLIC_SUPABASE_URL=...

Set EXPO_PUBLIC_MOCK_SUPERLIKE_NO_BOOST=true in development to force super_like to throw the same 409 DISCOVERY_SUPER_LIKE_REQUIRES_BOOST payload as the backend denial flow and open the RevenueCat paywall.

Set EXPO_PUBLIC_REVENUECAT_DISCOVERY_BOOSTS_OFFERING_ID if your boost paywall offering uses a different identifier than discovery_boosts.

Set EXPO_PUBLIC_REVENUECAT_DISCOVERY_SPOTLIGHT_OFFERING_ID if your spotlight paywall offering uses a different identifier than discovery_spotlight.

Set EXPO_PUBLIC_REVENUECAT_ENABLED=false to completely skip RevenueCat initialization for a build. When you are ready to ship purchases, switch it back to true and provide the real goog_... or appl_... public SDK key for that platform.

RevenueCat release builds should use the platform public SDK keys from your RevenueCat project such as goog_... for Android and appl_... for iOS. If no real SDK key is configured, or if a release build is still pointed at a test_... key, the app now leaves RevenueCat disabled instead of trying to initialize the purchase SDK and crashing at runtime.

Set EXPO_PUBLIC_MOCK_MATCHES_LIST_RESPONSE=success in development to render the typed mock matches list response while the backend endpoint is not ready yet.

Set EXPO_PUBLIC_MOCK_DISCOVERY_REWIND_RESPONSE to success, premium_required, or not_available in development to mock the rewind API path on the discovery deck.

Set EXPO_PUBLIC_MOCK_SPOTLIGHT_ACTIVATION_RESPONSE to success, no_credit, or already_active in development to mock the spotlight activation API path on the Matches screen.

  1. Start Expo
npx expo start
  1. Open the authenticated shell and visit the Products tab to see the React Query example.

Supabase Chat Experiment

The Google login path now creates a Supabase session directly and bypasses the email/WhatsApp verification screens. Email/password login still uses the existing backend verification flow.

Set up Supabase first:

  1. In Supabase Auth, enable Google and use the same Google project/client family as the app.
  2. Run supabase/chat-experiment-setup.sql in the Supabase SQL editor.
  3. Make sure messages and conversation_summaries are included in the supabase_realtime publication.
  4. If you use channel Presence/Broadcast, keep the realtime.messages policies from the setup script in place so room members can join room:<uuid> topics.

The inbox list now reads from conversation_summaries, a per-user summary table maintained by Postgres triggers. Message history still comes from messages, and the active room still subscribes at room:<conversationId> for message inserts, typing, and presence.

For the planned Figma-style chat UI database changes, see supabase/chat-figma-db-spec.md.

If your backend already uses public.users as the profile table, use supabase/chat-figma-backend-handoff.md as the handoff spec and do not add a duplicate profiles table.

To apply the first concrete schema step for that design, run supabase/chat-figma-schema.sql after the base chat setup script.

To extend chat from text-only messages to image/video/file messages, run supabase/chat-media-message-support.sql.

Two-emulator test flow

  1. Run the app on an iPhone simulator and an Android emulator.
  2. Sign in with a different Google account on each device.
  3. In Supabase SQL editor, run:
select id, email, created_at
from auth.users
order by created_at desc;
  1. Copy the two user IDs and replace USER_ID_ACCOUNT_A / USER_ID_ACCOUNT_B in the seed block inside supabase/chat-experiment-setup.sql.
  2. Open Google Test Room on both devices.
  3. Send a message from device A and confirm device B receives it in realtime.
  4. Send a message from device B and confirm device A receives it in realtime.
  5. Start typing on one device and confirm the other device sees the typing indicator.
  6. Background one device and confirm presence changes on the other device.
  7. Restart the app and confirm chat history still loads from Supabase.

Notes

  • The shared API layer already supports bearer-token injection when auth exists.
  • The Products demo uses the exact same shared fetch/query foundation as future real endpoints.
  • The current app uses Expo Router, React Query, SecureStore, NativeWind, and feature barrels together.
  • The discovery consumables contract for CON-60 is documented in docs/discovery-consumables-contract.md.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 95.1%
  • PLpgSQL 3.3%
  • JavaScript 1.5%
  • CSS 0.1%