CareConnect - Architecture Overview
Tech Stack
- Framework: Next.js 15 (App Router)
- Language: TypeScript
- Styling: Tailwind CSS v4 + Radix UI
- Database: Supabase (PostgreSQL + Vector)
- Internationalization:
next-intl(Support for EN, FR, AR, ZH-Hans, ES, PT, PA) - Testing: Playwright (E2E), Vitest (Unit)
Directory Structure
app/: Next.js App Router pages and API routes.[locale]/: Localized routes.api/v1/: RESTful API endpoints. (See OpenAPI Spec)[locale]/offline/: PWA offline page (Workbox navigation fallback targets/offline).worker.ts: Semantic search Web Worker.components/: UI components.ui/: Standardized primitives (Button, etc.).hooks/: Custom React hooks (useSearch,useServices).lib/: Utility functions (API helpers, search logic).types/: TypeScript definitions.messages/: Localization dictionaries (EN, FR, AR, ZH-Hans, ES, PT, PA).docs/: Project documentation.
Core Concepts
Search Architecture
The search system uses a hybrid approach:
graph TD
A[User Query] --> B{Keyword Search}
B -- Results Found --> C[Re-rank based on Relevance]
B -- Low/No Results --> D[Fuzzy Search Suggestion]
C --> E[Lazy Semantic Search Worker]
E --> F[Neural Re-ranking]
F --> G[Final Results Display]
A --> H[Search API POST - v16.0 Hybrid]
H --> I[Server-side Hybrid Scoring]
I --> G - Instant Keyword Search: Filters results locally/via basic db queries for immediate feedback.
- Fuzzy Search ("Did you mean?"): If results are low, the Levenshtein algorithm suggests alternative queries based on service names and tags.
- Lazy Semantic Search: Loads the optional WebLLM/WebGPU semantic stack in the background when the device supports it. Once ready, it re-ranks results based on vector similarity and on-device inference.
- Search API (v16.0 Enhancements): A server-side alternative (
POST /api/v1/search/services) that implements complex ranking factors including authority tiers, data completeness boosts, intent targeting, and continuous proximity decay. It uses a hybrid strategy: fetching candidates from the DB and scoring them in-memory using TypeScript logic to ensure consistency with client-side rankings. - Governance Freshness Enforcement: Both local and server search exclude records that fall outside the 180-day public-visibility window so stale listings do not keep ranking with only a soft penalty.
- Result Explainability: Public result cards and linked detail pages can surface normalized match reasons so users can inspect why a service ranked for their query.
Search Modes
The application supports two search modes, controlled by NEXT_PUBLIC_SEARCH_MODE:
- Local (Default): Downloads a compressed JSON bundle of all services. Search logic runs entirely in the browser. Best for offline support and zero-latency typing.
- Server: Sends
POSTrequests to the Librarian API. The server executes the query and returns results. Best for large datasets (>1000 items) and devices with limited RAM. (Note: Server mode does not load the JSON bundle, saving bandwidth).
AI Assistant Architecture
- Engine:
@mlc-ai/web-llm(WebGPU) running in a Web Worker for UI responsiveness. - Strategy: "LLM-as-Search" (query rewrite/expansion) + deterministic rendering of search results.
- Privacy:
- Local-Only: Inference runs entirely in the user's browser.
- No Data Egress: Queries never leave the device.
- Zero-Knowledge: Server knows that a user is chatting, but not what they are saying.
- Zero-Logging Search (v13.0): When using Server Search, queries are sent as
POST(no URL logs) withCache-Control: no-store. The databaseservices_publicview enforces a strict data boundary. - Lifecycle:
- Opt-In: Model download only triggered by explicit user action.
- Idle Cleanup: VRAM released after 5 minutes of inactivity.
Privacy-Preserving Personalization
- Client-Side Profile: User demographics (Age, Identities) stored in
localStorage(careconnect_user_context). - Zero PII: No user accounts, login, or cookies required for basic personalization.
- Local Eligibility: "Likely Qualify" checks run locally by parsing cached service data against the local profile.
- Identity Boosting: Search ranking adjustments happen on the client-side
WebWorker.
Data Pipelines
- Source of Truth: Manually curated service records remain authoritative. In development they live in
data/services.json; in production the app reads from Supabase when configured, with local JSON fallback when the database is unavailable.
sequenceDiagram
participant Curators as Curators + Research Inputs
participant Import as Validation + Import Scripts
participant DB as Verified Database
participant Embed as Embedding Generator
Curators->>Import: Verified JSON / CSV / seed files
Import->>Import: Normalize & validate schema
Import->>DB: Upsert curated records
DB->>Embed: Pull Verified Listings
Embed->>DB: Store Vector Embeddings
DB->>Client: JSON/API Delivery - Ingestion:
- Human-reviewed JSON, CSV, and municipal/provider seed files are validated before import.
scripts/import/geojson-import.ts: Generic utility for ingesting municipal (City of Kingston) and specialized (Indigenous/Faith) seed files.generate-embeddings.ts: Generates logical-semantic embeddings at build time.- Versioning:
generate-changelog.tstracks diffs between syncs.
User Feedback & Impact Loop (v14.0)
- Architecture: Privacy-preserving feedback system.
- Pipeline: Client (
FeedbackWidget) -> API (/api/v1/feedback) -> Supabase (feedbacktable). - Aggregations: Database materialized views (
feedback_aggregations,unmet_needs_summary) provide performant metrics for the/impactpage and Partner Dashboard. - Privacy: No PII, cookies, or persistent IDs are stored. Rate limiting is handled in-memory.
Equity-First Access (v14.0)
- Localization Parity: Full UI translation coverage for all 7 supported locales. Mandatory EN/FR parity for all service data.
- Simplified Views: Optional plain-language summaries (Grade 6-8 reading level) for high-impact services, stored in
plain_language_summaries. - Low-Bandwidth Outputs: Printable "Resource Cards" optimized for physical distribution and accessibility.
Visible Verification & Trust Signals (v14.0)
- Provenance:
TrustPaneldisplayslast_verifieddates, verification methods, and source provenance to build user confidence. - Verification Levels:
L1: Basic verification.L2: Manual verification by CareConnect team.L3: Partner-claimed and verified.L4: Governance-level policy concept for future partner/audit workflows; not currently represented in runtime types or search scoring.- Partner Update Workflow: Structured request-approval loop via
service_update_requestsensures data integrity while engaging service providers.
Push Notifications
- Technology: Web Push API + Service Worker (
app/worker.ts). - Flow: User Opt-In -> Service Worker Subscribes -> Endpoint stored in
push_subscriptions-> Server-side trigger via VAPID keys. - Privacy: No PII linked to subscriptions. User can revoked at any time via browser settings.
Automated Maintenance Bots
- URL Health Bot: Monthly check of all service URLs (
scripts/health-check-urls.ts). - Phone Validator: Connectivity checks using Twilio Lookup API (
scripts/validate-phones.ts). - Automation: GitHub Actions (
.github/workflows/health-check.yml) create issues for human review upon detection of failures.
Database Security & Row Level Security (RLS)
- Security Model: Supabase PostgreSQL with Row Level Security ensures data isolation and privacy.
- Public Views:
services_publicview created withsecurity_invoker = trueto use invoker's permissions (not definer's). - Hardened Policies: All INSERT policies validate foreign keys (e.g.,
service_id IN (SELECT id FROM services_public)) to prevent spam and invalid data. - Performance Optimizations: Auth function calls wrapped in scalar subqueries
(SELECT auth.uid())to avoid per-row re-evaluation. - Policy Consolidation: Separate policies for SELECT/INSERT/UPDATE/DELETE to avoid "Multiple Permissive Policies" performance warnings.
- Public Transparency: Aggregated metrics are exposed via Standard Views (
feedback_aggregations,unmet_needs_summary) that wrap underlying Materialized Views (mat_*). These wrappers enforcesecurity_invoker = trueto ensure the query runs with the user's permissions, satisfying security audits while maintaining API compatibility. - Documentation: See Database Security Guide for complete RLS policy documentation.
- Testing: RLS policies verified via
tests/integration/rls-policies.test.ts.
Partner Dashboard & RBAC
- Access Control: Role-Based Access Control (RBAC) implemented via
organization_memberstable. - Roles:
owner,admin,editor,viewer. - Functions: CRUD operations for listings, member invites (invite/accept flow), and analytics viewing.
- Multi-Lingual Content: Self-service editing for English and French fields (local services are EN/FR only).
Data Flow
- Services: Fetched via
/api/v1/services. Cached using SWR-like strategies in hooks. - Analytics: Search events are logged to
/api/v1/analytics/searchasynchronously.
v22 Phase 0 Pilot Instrumentation (Internal)
- Purpose: Capture pilot-only connection outcome signals before Phase 1 feature rollout.
- Internal Endpoints:
POST /api/v1/pilot/events/contact-attemptPOST /api/v1/pilot/events/connectionPOST /api/v1/pilot/events/referralPOST /api/v1/pilot/events/service-statusPOST /api/v1/pilot/events/data-decay-auditPOST /api/v1/pilot/events/preference-fitPATCH /api/v1/pilot/events/referral/{id}POST /api/v1/pilot/scope/servicesPOST /api/v1/pilot/metrics/recomputePOST /api/v1/pilot/integration-feasibilityGET /api/v1/pilot/metrics/scorecard- Security Model:
- Authenticated session required for all pilot endpoints.
- Organization-scoped authorization enforced for event writes and scorecard reads.
- Admin authorization required for integration feasibility decision writes.
- Privacy Constraints:
- Request payload validation rejects disallowed keys (
query,query_text,message,user_text,notes). - Raw query text is never accepted into pilot event contracts.
- Repeat-failure attribution uses opaque
entity_key_hashvalues rather than raw identifiers. - Resilience:
- Pilot DB operations use circuit-breaker-wrapped storage access.
- If pilot tables are not present, endpoints fail with explicit
501responses to prevent silent data loss. - Metric recompute writes canonical snapshots to
pilot_metric_snapshots; scorecard reads stay snapshot-based. - Readiness Reporting:
pilot_service_scopeis the canonical scoped-service source for bounded pilot readiness audits.npm run audit:pilot-readiness -- --pilot-cycle-id <id> [--org-id <uuid>]exports scoped JSON, Markdown, and CSV artifacts without mutating curated service data.docs/implementation/v22-pilot-readiness/contains the scope-file-first handoff bundle, including the runbook andscope.template.jsonfor cases where a committed pilot cycle does not yet exist.
Routing & Discovery
- Public Routes:
/service/[id]: Rich detail page./submit-service: Public crowdsourcing form./dashboard: Partner portal./about: Project mission and impact metrics. Includes Katarokwi Land Acknowledgment./about/partners: Data source transparency and verification process.- Provincial Services Discovery:
is_provincialflag allows services to be promoted in search results globally.- Provincial services display a "Province-Wide" badge for clarity.
- Language Selection:
LanguageSelectorcomponent inHeaderprovides 7-locale switching.- Arabic triggers RTL (Right-to-Left) direction in root layout.
- Internal Links:
ServiceCardnow links to internal detail pages instead of external URLs.
Partner Claim Workflow
- Claim Logic: Unclaimed services can be claimed by authenticated organizations.
- Verification: Claiming a service automatically elevates its status to
L1. - Atomic Operations:
lib/services.tshandles the claim logic with database consistency checks.
Hooks Architecture
We use a modular hook system to separate concerns:
- Search Hooks:
useSearchcoordindates state,useServiceshandles logic, anduseSemanticSearchmanages the worker. - Utility Hooks: Generic hooks for
localStorageandGeolocationensure SSR safety and consistency.
Logging & Monitoring
- Logger Utility: Located in
lib/logger.ts. Use instead ofconsole.log. - Error IDs: The Error Boundary generates unique IDs (e.g.,
ERR-K9X2J1) for cross-referencing logs with user reports.
User Interface & Accessibility
- High Contrast Mode: Global state managed via
useHighContrasthook, applying.high-contrastclass and CSS variable overrides. - Print Optimization: Specific
@media printstyles inglobals.cssandPrintButtoncomponent for physical delivery of information. - Data Freshness:
FreshnessBadgeprovides visual cues on the reliability of data based onlast_verified/provenance.verified_at, including an explicit expired state once a record crosses the 180-day governance limit. - Offline Safety Surfaces:
OfflineSnapshotStatusreads IndexedDB sync metadata (lastSync) and shows snapshot age plus stale-data warnings on offline surfaces when cached data may be outdated. - External Maps: Service-detail pages keep Google Maps loading opt-in. Directions remain available, but third-party map previews do not load until the user explicitly requests them.
- Search Explainability Surfaces:
ServiceMatchReasonsshows deduplicated match reasons on result cards and on detail pages when the user follows a search result with ranking context attached.
Development
npm run dev: Start local server.npm run test: Run the default Vitest suite.npm run test:db: Run real DB-backed retrieval and policy tests.npm run test:e2e:local: Run partial E2E tests (CI handles full suite).AGENTS.md: Contributor and local workflow guidance.docs/development/testing-guidelines.md: Detailed testing guidance.