# 📘 Project Best Practices ## 1. Project Purpose LynkedUp is a mobile-first, SDK-driven application suite with enterprise-grade security and offline-first capabilities. It is structured as a PNPM monorepo orchestrated by Nx, providing modular Core SDKs (security, storage, sync, policy, trust) and Feature SDKs (auth, tasks, messaging, etc.) consumed by React Native apps and a Node.js GraphQL BFF. ## 2. Project Structure - Monorepo - apps/ - lynkedup-pro/ and lynkedup-foundation/: React Native apps demonstrating SDK composition. - api-bff/: Node.js Fastify + Apollo GraphQL Backend For Frontend. - sdk-playground/: Development sandbox for SDKs. - packages/ - core/: Tier-0 infrastructure SDKs (e.g., security, storage, sync, policy-client, runtime, trust).# 📘 Project Best Practices ## 1. Project Purpose LynkedUp is a mobile-first, SDK-driven application suite with enterprise-grade security and offline-first capabilities. It is structured as a PNPM monorepo orchestrated by Nx, providing modular Core SDKs (security, storage, sync, policy, trust) and Feature SDKs (auth, tasks, messaging, etc.) consumed by React Native apps and a Node.js GraphQL BFF. ## 2. Project Structure - Monorepo - apps/ - lynkedup-pro/ and lynkedup-foundation/: React Native apps demonstrating SDK composition. - api-bff/: Node.js Fastify + Apollo GraphQL Backend For Frontend. - sdk-playground/: Development sandbox for SDKs. - packages/ - core/: Tier-0 infrastructure SDKs (e.g., security, storage, sync, policy-client, runtime, trust). - feature-*/: Tier-1 feature SDKs following clean architecture (domain, data, ui-rn). - shared/: Common types, config, and UI kit. - Tooling & Config: Nx, ESLint, Prettier, Changesets, Commitlint. - Separation of concerns (Clean Architecture conventions) - Feature SDKs: - domain/: Pure business logic (use cases, entities, interfaces). No platform or infra dependencies. - data/: Repositories/adapters that implement domain interfaces and talk to core SDKs and BFF. - ui-rn/: React Native components and navigation. - Core SDKs provide foundational services (e.g., SecurityCore, StorageCore) that feature data layers depend on. - Apps initialize and compose SDKs; they own configuration and feature toggles. - Entry points & configuration - apps/api-bff/src/main.ts: Fastify server + Apollo schema wiring and middleware registration. - apps/*/App.tsx: SDK initialization sequence (Security → Storage → Sync → Runtime → Trust) and navigation bootstrapping. - packages/*/src/index.ts: Barrel files re-exporting public API for each package. - tsconfig.base.json: Strict TypeScript with path aliases for all packages. ## 3. Test Strategy - Framework: Jest (Nx managed). Use per-package unit tests with co-located *.spec.ts(x) files. - Suggested organization (based on architecture): - Domain layer: Unit tests for use cases (pure, no I/O). Mock via interfaces. - Data layer: Contract tests for GraphQL and network using MSW; integration tests with core SDKs. - Core SDKs: Unit tests for deterministic logic; integration tests for cross-SDK interactions. - Apps: E2E tests with Detox for key flows. - Mocking guidelines: - Mock via domain interfaces (e.g., IAuthRepository, ITrustRepository) rather than concrete classes. - For GraphQL, prefer MSW to mock network boundaries rather than stubbing internals. - Use dependency injection to pass fakes/mocks into use cases. - Coverage expectations: - Aim high on domain logic (>90%). - Maintain pragmatic coverage for data/adapters; prefer integration and contract tests. - CI: - Use nx affected:test for efficient runs. ## 4. Code Style - Languages & typing - TypeScript with strict mode enabled. Prefer precise types and interfaces over any. - Public APIs should have explicit return types (ESLint warns on missing types). - Favor async/await over promise chains; avoid top-level side effects. - Naming conventions - Classes: PascalCase (e.g., SecurityCore, LoginUseCase). - Functions/variables: camelCase. - Files: index.ts as package barrels; core classes often use PascalCase file names (e.g., SecurityCore.ts). Keep barrels aligned with actual exports. - Packages follow scopes (@core/*, @feature-*/domain|data|ui-rn, @shared/*). - Formatting - Prettier: singleQuote, semi, printWidth 100, arrowParens avoid, LF line endings. - Enforced via lint-staged on staged files. - Lint rules & boundaries - ESLint: no-unused-vars (ignore args prefixed with _), explicit-function-return-type warn. - Module boundaries via @nx/enforce-module-boundaries with tags: - type:domain → only depend on [type:domain, type:types, scope:shared]. - type:data → depend on [type:domain, type:types, scope:core, scope:shared]. - type:ui → depend on [type:data, type:domain, type:types, scope:shared]. - scope:feature cannot depend on other scope:feature. - scope:core only depends on [scope:core, scope:shared, type:types]. - platform:shared cannot depend on platform:rn or platform:node. - Ensure each Nx library is properly tagged to satisfy these constraints. - Documentation & comments - Use concise JSDoc for public APIs and to mark FRD references (e.g., F.SC.004). - Map errors to user-friendly codes/messages at boundaries (see LoginUseCase.handleLoginError). - Error handling - Guard methods with ensureInitialized() where applicable (e.g., SecurityCore, StorageCore). - On server, do not expose internals in production (see BFF formatError). ## 5. Common Patterns - Clean Architecture layering (UI → Data → Domain → Shared Types) and dependency inversion via interfaces. - SDK initialization order in apps: Security → Storage → Sync → Runtime → Trust → Feature SDKs. - Barrel exports (index.ts) per package for a stable public surface. - GraphQL BFF: - Fastify plugins for security (helmet, cors) and custom plugins (security, rateLimit). - Middleware order: DPoP → Auth → Policy (ABAC) before GraphQL handler. - Dynamic imports for optional dependencies (e.g., Permit.io client). - Security & cryptography - Hardware-backed keys, DPoP proof generation, envelope encryption with organizational DEKs. - Cryptographic erasure and secure wipe via key management. - Offline-first storage - Encrypted local DB, schema registry, selective purge by organization, re-keying (planned). ## 6. Do's and Don'ts - Do - Initialize core SDKs in the documented order before feature initialization. - Keep domain logic pure and free from platform or network code. - Depend on interfaces in domain; implement in data with adapters to core SDKs/BFF. - Use path aliases from tsconfig.base.json; export public API via index.ts. - Respect ESLint module boundaries and Nx tags; add proper library tags when creating new packages. - Map server errors to safe messages in production; log full details server-side only. - Use MSW for network contract tests; keep unit tests fast and deterministic. - Follow Conventional Commits with configured scopes and the additional `security` type. - Keep barrel files accurate and synchronized with actual implementation files. - Don't - Import across features (no feature-to-feature dependencies). - Make domain depend on data/core/platform code. - Bypass ensureInitialized guards in core SDKs. - Expose stack traces or sensitive details to clients in production. - Hardcode secrets or environment-specific values; use config and env vars. - Introduce Node-specific APIs into React Native code paths. ## 7. Tools & Dependencies - Tooling - PNPM workspaces + Nx orchestration (caching, affected commands). - ESLint + Prettier + lint-staged; commitlint with conventional commits. - Changesets for versioning and publishing (SDK packages only). - Key libraries - Apps: React Native, React Navigation. - BFF: Fastify, @apollo/server, @graphql-tools/schema, @fastify/cors, @fastify/helmet, optional Permit.io. - Core SDKs: Security (DPoP, key management, encryption), Storage (encrypted DB, schema registry), Sync/Runtime/Trust (per architecture). - Setup - Install: pnpm install; build: pnpm nx run-many -t build. - Dev scripts: dev:playground, dev:pro, dev:foundation. - Tests: pnpm test or pnpm affected:test. - BFF env vars: NODE_ENV, PORT (default 4000), HOST (default 0.0.0.0), PERMIT_PDP_URL, PERMIT_API_KEY. - Separation of concerns (Clean Architecture conventions) - Feature SDKs: - domain/: Pure business logic (use cases, entities, interfaces). No platform or infra dependencies. - data/: Repositories/adapters that implement domain interfaces and talk to core SDKs and BFF. - ui-rn/: React Native components and navigation. - Core SDKs provide foundational services (e.g., SecurityCore, StorageCore) that feature data layers depend on. - Apps initialize and compose SDKs; they own configuration and feature toggles. - Entry points & configuration - apps/api-bff/src/main.ts: Fastify server + Apollo schema wiring and middleware registration. - apps/*/App.tsx: SDK initialization sequence (Security → Storage → Sync → Runtime → Trust) and navigation bootstrapping. - packages/*/src/index.ts: Barrel files re-exporting public API for each package. - tsconfig.base.json: Strict TypeScript with path aliases for all packages. ## 3. Test Strategy - Framework: Jest (Nx managed). Use per-package unit tests with co-located *.spec.ts(x) files. - Suggested organization (based on architecture): - Domain layer: Unit tests for use cases (pure, no I/O). Mock via interfaces. - Data layer: Contract tests for GraphQL and network using MSW; integration tests with core SDKs. - Core SDKs: Unit tests for deterministic logic; integration tests for cross-SDK interactions. - Apps: E2E tests with Detox for key flows. - Mocking guidelines: - Mock via domain interfaces (e.g., IAuthRepository, ITrustRepository) rather than concrete classes. - For GraphQL, prefer MSW to mock network boundaries rather than stubbing internals. - Use dependency injection to pass fakes/mocks into use cases. - Coverage expectations: - Aim high on domain logic (>90%). - Maintain pragmatic coverage for data/adapters; prefer integration and contract tests. - CI: - Use nx affected:test for efficient runs. ## 4. Code Style - Languages & typing - TypeScript with strict mode enabled. Prefer precise types and interfaces over any. - Public APIs should have explicit return types (ESLint warns on missing types). - Favor async/await over promise chains; avoid top-level side effects. - Naming conventions - Classes: PascalCase (e.g., SecurityCore, LoginUseCase). - Functions/variables: camelCase. - Files: index.ts as package barrels; core classes often use PascalCase file names (e.g., SecurityCore.ts). Keep barrels aligned with actual exports. - Packages follow scopes (@core/*, @feature-*/domain|data|ui-rn, @shared/*). - Formatting - Prettier: singleQuote, semi, printWidth 100, arrowParens avoid, LF line endings. - Enforced via lint-staged on staged files. - Lint rules & boundaries - ESLint: no-unused-vars (ignore args prefixed with _), explicit-function-return-type warn. - Module boundaries via @nx/enforce-module-boundaries with tags: - type:domain → only depend on [type:domain, type:types, scope:shared]. - type:data → depend on [type:domain, type:types, scope:core, scope:shared]. - type:ui → depend on [type:data, type:domain, type:types, scope:shared]. - scope:feature cannot depend on other scope:feature. - scope:core only depends on [scope:core, scope:shared, type:types]. - platform:shared cannot depend on platform:rn or platform:node. - Ensure each Nx library is properly tagged to satisfy these constraints. - Documentation & comments - Use concise JSDoc for public APIs and to mark FRD references (e.g., F.SC.004). - Map errors to user-friendly codes/messages at boundaries (see LoginUseCase.handleLoginError). - Error handling - Guard methods with ensureInitialized() where applicable (e.g., SecurityCore, StorageCore). - On server, do not expose internals in production (see BFF formatError). ## 5. Common Patterns - Clean Architecture layering (UI → Data → Domain → Shared Types) and dependency inversion via interfaces. - SDK initialization order in apps: Security → Storage → Sync → Runtime → Trust → Feature SDKs. - Barrel exports (index.ts) per package for a stable public surface. - GraphQL BFF: - Fastify plugins for security (helmet, cors) and custom plugins (security, rateLimit). - Middleware order: DPoP → Auth → Policy (ABAC) before GraphQL handler. - Dynamic imports for optional dependencies (e.g., Permit.io client). - Security & cryptography - Hardware-backed keys, DPoP proof generation, envelope encryption with organizational DEKs. - Cryptographic erasure and secure wipe via key management. - Offline-first storage - Encrypted local DB, schema registry, selective purge by organization, re-keying (planned). ## 6. Do's and Don'ts - Do - Initialize core SDKs in the documented order before feature initialization. - Keep domain logic pure and free from platform or network code. - Depend on interfaces in domain; implement in data with adapters to core SDKs/BFF. - Use path aliases from tsconfig.base.json; export public API via index.ts. - Respect ESLint module boundaries and Nx tags; add proper library tags when creating new packages. - Map server errors to safe messages in production; log full details server-side only. - Use MSW for network contract tests; keep unit tests fast and deterministic. - Follow Conventional Commits with configured scopes and the additional `security` type. - Keep barrel files accurate and synchronized with actual implementation files. - Don't - Import across features (no feature-to-feature dependencies). - Make domain depend on data/core/platform code. - Bypass ensureInitialized guards in core SDKs. - Expose stack traces or sensitive details to clients in production. - Hardcode secrets or environment-specific values; use config and env vars. - Introduce Node-specific APIs into React Native code paths. ## 7. Tools & Dependencies - Tooling - PNPM workspaces + Nx orchestration (caching, affected commands). - ESLint + Prettier + lint-staged; commitlint with conventional commits. - Changesets for versioning and publishing (SDK packages only). - Key libraries - Apps: React Native, React Navigation. - BFF: Fastify, @apollo/server, @graphql-tools/schema, @fastify/cors, @fastify/helmet, optional Permit.io. - Core SDKs: Security (DPoP, key management, encryption), Storage (encrypted DB, schema registry), Sync/Runtime/Trust (per architecture). - Setup - Install: pnpm install; build: pnpm nx run-many -t build. - Dev scripts: dev:playground, dev:pro, dev:foundation. - Tests: pnpm test or pnpm affected:test. - BFF env vars: NODE_ENV, PORT (default 4000), HOST (default 0.0.0.0), PERMIT_PDP_URL, PERMIT_API_KEY.