Live project memory
Live project memory
Last updated 5/3/2026
ZoomProp Live Project Memory
zoomprop/zp-alpha — Persistent Cross-Session State Document
Document version: Generated from repository state post-PR #464 merge
Platform version: 0.1.0 (pre-production alpha)
Primary stack: Next.js 15 (Turbopack) · TypeScript · Clerk · LangChain/LangGraph · Elasticsearch · Mapbox · Knock · Radix UI
1. Current Project State
1.1 What Has Been Built
ZoomProp is an AI-augmented real estate investment intelligence platform in active alpha development. The following surface areas are substantively implemented:
| Domain | Status | Key Files |
|---|---|---|
| Authentication & Onboarding | Functional | src/app/(auth)/onboarding/ — 10-step wizard with billing, identity, geographic focus, co-investment |
| AI Chat System | Functional, actively iterated | src/app/api/ai/chat/route.ts, src/app/api/ai/conversations/ |
| Property Discovery + Maps | Functional, recent bug fixes | src/app/api/actions/analyze-property-investigation/route.ts, Mapbox + Google Maps integration |
| Alert / Notification System | Functional | src/app/api/alerts/ (7 routes), Knock integration, src/app/(dashboard)/alerts/ |
| Analytics Dashboard | Partial | src/app/api/analytics/ (5 routes: appreciation, markets, performance, portfolio, properties) |
| Portfolio Management | Partial | src/app/api/analytics/portfolio/route.ts, watchlist features |
| AI Analysis Suite | Partial | 10+ AI routes covering property, commercial, maintenance, offer, inspection, and intent analysis |
| Search (Elasticsearch) | Functional | @elastic/elasticsearch ^8.18.2; legacy backup routes archived under archive/legacy-api-backup/elastic-search/ |
| Theme System | In repair (PR #458 open) | Custom ThemeProvider + use-theme hook decoupled from shadcn default |
| Automation / Pipelines | Scaffolded | src/app/api/automation/analytics/route.ts, src/app/api/automation/board-config/route.ts |
| Freemium / Subscription | Partial | PR #455 merged: monthly free query grant API + context injection for unpaid users |
| Staging CI | Repaired (PR #463 merged) | Orchestrator cost guards added |
| Chat Artifact Action Plans | Scaffolded (PR #462 merged) | M1–M5 milestone plan + verifier fixes in chat-onboarding/ |
1.2 What Is In Progress
Active PRs (open, not yet merged):
| PR | Description | Risk |
|---|---|---|
| #458 | Theme persistence: wire use-theme to custom ThemeProvider | Medium — touches global state |
| #396 | Mobile fixes (taha/mobile-fixes) | Low-medium — long-lived, may have merge conflicts |
| #379 | Radar chart cleanup (shabaan/radar-cleanup) | Low |
| #378 | Chat shell: display all questions to match total suggested count | Low |
| #362 | Update ChatEmptyState prompts + QuickActionsGrid enhancements | Low |
| #358 | Correct icons for questions when relevant filter is applied | Low |
| #356 | Sign-in page card padding fix | Low |
In-codebase work tracked by planning docs (not yet PRs):
context/COLLECTIONS_IMPLEMENTATION_ACTION_PLAN.md+context/COLLECTIONS_UX_UPGRADE_ACTION_PLAN.md— collections feature planned but not fully wiredcontext/PIPELINES_IMPLEMENTATION_ROADMAP.md— automation pipeline UI scaffolded, backend incompletecontext/PROCEDURES_COMPLETE_INTEGRATION_PLAN.md(multiple iterations) — procedures API integration ongoingcontext/DISCOVER_PAGE_ACTION_PLAN.md— discover page maps fix merged (#459), but further work trackedchat-onboarding/CASH_FLOW_ANALYSIS_IMPROVEMENT_PLAN.md— cash flow analysis accuracy improvement planned
1.3 What Is Blocked
- TECH-001
ignoreBuildErrors: trueandignoreDuringBuilds: trueare set innext.config.ts. TypeScript and ESLint errors are silently swallowed in production builds. Cannot confidently assess build health without removing these flags. - TECH-002 Mobile responsiveness (PR #396) has been open without merge — suggests either ongoing instability or insufficient reviewer bandwidth.
- TECH-003 Theme persistence (PR #458) is open, indicating the theme system is still broken for end users in production.
- TECH-004 Several chat-related PRs (#378, #362, #358) are open simultaneously, suggesting the chat shell UI is in a partially inconsistent state.
2. Active Decisions and Their Rationale
ARCH-001 · Next.js App Router with Turbopack
Decision: Use next dev --turbopack for local development.
Rationale: Faster HMR given 500-file codebase. Turbopack is still pre-stable for some edge cases — team is tolerating occasional build quirks in exchange for dev speed.
Status: Active. No known Turbopack-specific blockers in recent commits.
ARCH-002 · Clerk for Auth (Elements + Next.js SDK)
Decision: Use @clerk/nextjs ^6.23.1 with @clerk/elements ^0.23.35 for custom sign-in/sign-up UI.
Rationale: Clerk handles org-based multi-tenancy (real estate teams/brokerages) without building RBAC from scratch. @clerk/elements gives full UI control for branded auth pages.
Active concern: src/app/api/auth/active-org/route.ts and src/app/api/auth/session/route.ts suggest org-switching logic is custom — watch for Clerk version upgrade breaking changes.
ARCH-003 · Dual AI Stack: Vercel AI SDK + LangChain/LangGraph
Decision: @ai-sdk/openai ^2.0.30 + @ai-sdk/react ^2.0.72 for streaming chat; @langchain/core, @langchain/community, @langchain/langgraph for complex multi-step agent workflows.
Rationale: Vercel AI SDK handles streaming UX (chat completions). LangGraph handles stateful, multi-node workflows (property investigation pipelines, persona-aware analysis).
Active concern: serverExternalPackages: ['langchain', '@langchain/core', '@langchain/community'] in next.config.ts — these must stay server-side only. Any accidental client import will cause bundle bloat or runtime errors.
ARCH-004 · Knock for Notifications
Decision: @knocklabs/client ^0.15.1 + @knocklabs/react ^0.7.25 + @knocklabs/node ^1.11.1.
Rationale: Knock provides pre-built notification infrastructure (in-app, email, push) without custom queue/delivery logic. The alerts/ API surface (7 routes) maps to Knock workflows.
Status: Alert testing CI workflow exists at .github/workflows/alert-testing.yml.
ARCH-005 · Dual Mapping: Mapbox + Google Maps
Decision: Both @mapbox/mapbox-gl-draw ^1.5.0 + @googlemaps/js-api-loader ^1.16.10 are present.
Rationale: Mapbox GL Draw used for polygon-based geographic search/filters on the Discover page. Google Maps used for property-level static images (confirmed by maps.googleapis.com in next.config.ts image domains).
Active concern: Two mapping SDKs increase bundle size and API cost surface. No documented plan to consolidate.
ARCH-006 · Elasticsearch for Property Search
Decision: @elastic/elasticsearch ^8.18.2 — direct client in Next.js API routes.
Rationale: Legacy architecture from earlier platform. The archive/legacy-api-backup/elastic-search/ directory confirms the search routes have already been migrated once.
Active concern: Connecting to Elasticsearch directly from serverless Next.js API routes is connection-pool hostile. No connection pooling strategy is documented.
ARCH-007 · Freemium Query Gating
Decision (PR #455, merged): Monthly free query grants are issued via /api/auth/active-org or a new endpoint; context is injected into AI routes for unpaid users.
Rationale: Enables public demo/trial without full subscription. Supports demo-fixing sprint.
Status: Newly merged. Integration tests not confirmed.
ARCH-008 · Archive Strategy for Legacy Code
Decision: Legacy API routes are preserved under archive/legacy-api-backup/ rather than deleted.
Rationale: Reference and rollback safety during migration. The archive contains ~60 routes including Plaid, HelloSign, Stripe, Middesk, crowdfunding — indicating significant platform scope reduction or deferral.
Risk: Archive grows unbounded without a scheduled deletion policy.
3. Recent Changes and Their Impact
Last 15 Commits (post-PR #456)
| Commit | Change | Impact |
|---|---|---|
08ce25f | Merge PR #460 (taha/fixes-2.0) | Watchlist + dashboard + chat fixes bundled |
d7b9eb1 | Prettier format sweep | No logic change; reduces diff noise in future PRs |
218b8ea | Watchlist and dashboard fixes | Dashboard state stability improved |
4e60fd8 | Chat fixes | Chat shell stability — specific issue unclear from message alone |
ee3b2fa | Merge PR #459 (discover maps fix) | Mapbox draw/layer rendering on Discover page repaired |
bffa42f + 1c236d8 | Maps fix 2.0 + 1.0 | Iterative map repair — two commits suggests first attempt was incomplete |
69c94a5 | Merge PR #457 (demo-fixing) | Chart text/legend theme toggle fix for region + demographics charts |
525ab5e | Fix chart text on theme toggle | Theme-aware chart rendering — partial fix (full theme persistence still in PR #458) |
3d5e9ec | Update auth redirect UI loader | Improved perceived performance during org redirect |
3a74c26 | Monthly free queries grant + context | Freemium AI usage gating implemented |
432c335 | Fix z-index of investment strategy dropdown | UI layering bug on dashboard |
Pattern observation: The recent commit stream is dominated by demo-fixing and stability patches, not new feature development. The project is in a stabilization sprint, likely ahead of a demo or investor review.
4. Open Questions and Unresolved Trade-offs
OQ-001 · LangGraph vs. Vercel AI SDK routing boundary
The codebase uses both @ai-sdk/react streaming and @langchain/langgraph for agent workflows. The boundary between "simple chat completions" (AI SDK) and "complex property investigation" (LangGraph) is not formally documented. As AI features grow, this boundary will become a source of inconsistency.
OQ-002 · Elasticsearch connection management in serverless
Direct @elastic/elasticsearch client instantiation in Next.js API routes does not play well with serverless cold starts and connection limits. No connection singleton pattern is confirmed in the current codebase surface.
OQ-003 · Dual mapping SDK consolidation
Mapbox and Google Maps coexist. No ADR documents why both are retained. If Google Maps is only used for static image URLs (confirmed in next.config.ts), the @googlemaps/js-api-loader runtime dependency may be unnecessary.
OQ-004 · Archive deletion schedule
archive/legacy-api-backup/ contains ~60+ route files. Plaid, HelloSign, Middesk, crowdfunding, and Stripe routes are archived. There is no documented plan for when these are formally deleted or whether any are candidates for re-activation.
OQ-005 · TypeScript + ESLint build suppression
ignoreBuildErrors: true and ignoreDuringBuilds: true are dangerous in a production path. The trade-off is development velocity vs. correctness guarantees. No milestone exists to remove these flags.
OQ-006 · Mobile responsiveness debt
PR #396 (taha/mobile-fixes) has been open without merge. The platform's mobile story is unresolved. Whether ZoomProp targets mobile browsers at all is undocumented.
OQ-007 · Procedures API iteration count
There are 7 separate planning documents for the Procedures API integration (context/PROCEDURES_*.md). This suggests repeated replanning rather than steady execution. Root cause (API instability? requirements churn?) is not documented.
OQ-008 · Subscription/billing architecture post-archive
The legacy backup contains Stripe checkout, subscription, portal, and payment routes. The current active API surface has no visible Stripe routes. The freemium grant (PR #455) suggests a billing model exists, but the payment collection mechanism is unclear from current active routes.
5. Key Learnings from Recent Development Sessions
LEARN-001 · Demo sprints require dedicated fix bandwidth
The last ~15 commits are almost entirely fixes rather than features. The demo-fixing branch pattern indicates that demo preparation is a recurring forcing function. Consider maintaining a persistent demo environment that lags behind main to avoid this pressure.
LEARN-002 · Theme system was undertested
The chart theme toggle bug (commit 525ab5e) and the open PR #458 for theme persistence reveal that the custom ThemeProvider was built without sufficient integration coverage. The existing test suite covers auth and layout components but not theme-dependent chart rendering.
LEARN-003 · Map fixes required two passes
Commits 1c236d8 (maps fix 1.0) and bffa42f (fix 2.0) show that the Discover page map fix was not complete on first attempt. Mapbox GL integration with Next.js App Router SSR boundaries remains fragile and should be E2E tested.
LEARN-004 · Planning docs outpace implementation
The context/ directory contains 40+ markdown planning documents. The volume of planning docs (especially for Procedures — 7 docs) suggests planning is not translating cleanly to implementation. Future sessions should link planning docs to specific PRs and track completion status.
LEARN-005 · Freemium gating added late in sprint The free query grant (PR #455) was added during what appears to be a demo-stabilization sprint. Late-stage monetization logic additions carry integration risk. This feature needs explicit test coverage before relying on it in demos.
LEARN-006 · AI route proliferation needs governance
There are 16 AI-prefixed API routes (/api/ai/*). Without a documented routing taxonomy, adding new AI capabilities creates route sprawl. The @api/ai/intent route suggests intent classification before routing — this pattern should be formalized.
6. Architectural Evolution
Phase 0 → Legacy Platform (Archived)
The archive/legacy-api-backup/ directory reveals a substantially broader platform: crowdfunding projects, Plaid financial verification, HelloSign document signing, Middesk business verification, lender/borrower matching, investor management, webinars, email campaigns, and full Stripe billing. This was a fintech-adjacent real estate platform.
Phase 1 → AI-First Pivot (Current Alpha)
The active codebase represents a deliberate narrowing to AI-powered property intelligence. The retained capabilities are: search, discovery, portfolio analytics, alerts, and AI chat/analysis. The complex financial transaction infrastructure (Plaid, Stripe, HelloSign, Middesk) has been archived but not deleted.
Phase 2 → Freemium + Subscription (In Progress)
PR #455 introduces the first visible freemium boundary in the active codebase. The monthly free query grant suggests a usage-based freemium model layered on top of Clerk's organization membership.
Phase 3 → Automation + Pipelines (Scaffolded)
context/PIPELINES_IMPLEMENTATION_ROADMAP.md and src/app/api/automation/ routes indicate a planned CRM/workflow automation layer. Two automation routes exist but the feature is not user-visible yet.
Notable Structural Decisions
- Route Groups:
(auth)and(dashboard)route groups provide clean layout separation in App Router. - Context engineering: The
context/directory is used as a human-readable knowledge base for AI-assisted development sessions (.cursor/mcp.jsonpresent,.claude/settings.local.jsonpresent) — the repository itself is tooled for LLM-assisted development. zp-fetch-service/Dockerfile: A sidecar fetch service exists with its own Dockerfile, suggesting the ZoomProp API backend (NEXT_PUBLIC_ZOOMPROP_API_URL_V1) is a separate service, not colocated.
7. Technical Debt Inventory
| ID | Description | Location | Priority | Notes |
|---|---|---|---|---|
| TECH-001 | ignoreBuildErrors + ignoreDuringBuilds: true masks type/lint errors in CI | next.config.ts | P0 | Must be resolved before production |
| TECH-002 | No Elasticsearch connection singleton/pool management | src/app/api/* routes using ES client | P1 | Serverless cold-start risk |
| TECH-003 | PR #458 open: theme persistence broken | ThemeProvider, use-theme | P1 | Active UX regression |
| TECH-004 | PR #396 open: mobile responsiveness unresolved | Dashboard/discover UI | P1 | Platform unusable on mobile |
| TECH-005 | Dual mapping SDKs (Mapbox + Google Maps) | package.json, Discover page | P2 | Bundle bloat, API cost duplication |
| TECH-006 | archive/ directory has no deletion policy | archive/legacy-api-backup/ | P2 | ~60+ files adding cognitive overhead |
| TECH-007 | 7 Procedures planning docs with unclear completion state | context/PROCEDURES_*.md | P2 | Planning debt, not code debt |
| TECH-008 | No documented LangGraph/AI SDK routing boundary | src/app/api/ai/* | P2 | 16 AI routes with inconsistent patterns |
| TECH-009 | context/ planning docs not linked to PRs/tickets | context/*.md | P2 | Knowledge fragmentation |
| TECH-010 | Test coverage gap: theme rendering, map components, freemium gating | tests/ | P2 | 86 test files, but key UI paths untested |
| TECH-011 | No E2E coverage for Discover page map interactions | tests/ | P3 | Mapbox mock exists but map draw untested |
| TECH-012 | Subscription/payment path unclear in active routes | src/app/api/ | P3 | Stripe archived; new model undocumented |
| TECH-013 | @ai-sdk/openai at ^2.0.30 and @ai-sdk/react at ^2.0.72 — major version drift | package.json | P3 | Potential API surface mismatch |
| TECH-014 | Python api_tests/ suite exists but integration with CI unclear | api_tests/, .github/workflows/ | P3 | Four GitHub workflows present but Python tests not confirmed wired |
8. Team Conventions and Patterns
Branch Naming
taha/[feature-or-fix]— developer-prefixed feature branchesshabaan/[feature]— same patternabdullah/[feature]— same patterndemo-fixing— shared stabilization branch used across developersM[n]:prefix in PR titles (PRs #462–464) — milestone-tagged contract/foundation PRs
Commit Style
- Conventional commits partially adopted:
feat:,fix:,style:,docs(...): - Many commits use plain English without conventional prefix (e.g.,
"watchlist and dashboard fixes") - Prettier format sweeps are committed as standalone
style: format code with Prettiercommits
PR Templates
GitHub PR templates exist for feature, bugfix, and hotfix under .github/PULL_REQUEST_TEMPLATE/. Usage appears inconsistent given short commit messages in recent history.
Code Quality Tooling
- Husky pre-commit hook via
.husky/pre-commit - Prettier +
.prettierrc.json— enforced viaformat:checkscript - ESLint — configured but bypassed in builds
- Codacy —
.codacy.ymlpresent (static analysis CI integration) - DeepSource —
.deepsource.tomlpresent (automated code review) - Audit CI —
.auditcircpresent (dependency vulnerability scanning) - Vitest for unit tests; Playwright for E2E
AI-Assisted Development
.cursor/mcp.jsonand.claude/settings.local.jsonconfirm Cursor and Claude are active development toolscontext/directory serves as a structured knowledge base for LLM context injectiontools/scripts/theme-audit-runner.ts— custom tooling for theme compliance auditing
Zod Validation Pattern
Zod schemas are used for runtime validation with explicit transform and refine steps. The CapRateBaseSchema in the database schema file demonstrates the pattern: string-or-number union inputs, NaN guards, default values. This pattern should be assumed across all form inputs.
Component Organization
src/app/(route-group)/_components/— co-located, route-scoped componentssrc/components/core/— shared layout and auth components with test coveragecomponents.jsonpresent — shadcn/ui component registry in use
9. Integration Points and Their Current Health
| Integration | Package / Endpoint | Health | Notes |
|---|---|---|---|
| Clerk Auth | @clerk/nextjs ^6.23.1 | ✅ Functional | Auth redirect loader recently improved |
| OpenAI | @ai-sdk/openai ^2.0.30 | ✅ Functional | Used in 16 AI routes |
| LangChain/LangGraph | @langchain/langgraph ^0.3.5 | ✅ Functional (serverside only) | Must remain in serverExternalPackages |
| Elasticsearch | @elastic/elasticsearch ^8.18.2 | ⚠️ Connection risk | No pool management documented |
| Mapbox GL | @mapbox/mapbox-gl-draw ^1.5.0 | ⚠️ Recently repaired | Two-pass fix suggests fragility |
| Google Maps | @googlemaps/js-api-loader ^1.16.10 | ❓ Unknown | Static images confirmed; runtime loader usage unclear |
| Knock Notifications | @knocklabs/node ^1.11.1 | ✅ Functional | Alert testing CI workflow active |
| ZoomProp Backend API | NEXT_PUBLIC_ZOOMPROP_API_URL_V1 | ❓ Unknown | Separate service; zp-fetch-service/Dockerfile present |
| ZoomProp WebSocket | NEXT_PUBLIC_ZOOMPROP_WEBSOCKET_URL | ❓ Unknown | Configured but runtime health unverified |
| Stripe (legacy) | Archived | 🔴 Inactive | 8 routes in archive; no active Stripe routes |
| Plaid (legacy) | Archived | 🔴 Inactive | 10 routes in archive |
| OpenTelemetry | @opentelemetry/api ^1.9.0 | ❓ Unknown | Package present; instrumentation depth unclear |
| DnD Kit | @dnd-kit/core ^6.3.1 | ✅ Present | Used in automation board/pipeline UI |
10. Performance Baselines and Optimization Opportunities
Known Performance Risks
PERF-001 · Bundle size — dual mapping SDKs
mapbox-gl + @mapbox/mapbox-gl-draw + @googlemaps/js-api-loader are all client-loaded. Mapbox GL alone is ~900KB uncompressed. Google Maps JS API adds a further runtime-loaded payload. Without dynamic imports with ssr: false, map components will fail SSR and bloat the initial bundle.
PERF-002 · LangChain in serverless
LangChain community packages are large. They are correctly excluded from client bundles via serverExternalPackages but cold start times on LangGraph-heavy routes (e.g., /api/actions/analyze-property-investigation) will be high. No caching layer (Redis, edge cache) is visible in the active route surface.
PERF-003 · AI route latency without streaming
Routes like /api/ai/property-analysis and /api/ai/commercial-analysis are full-response routes (not streaming). Large LLM responses without streaming create long TTFB. Only /api/ai/chat is confirmed streaming via @ai-sdk/react.
PERF-004 · Image domain allowlist breadth
next.config.ts allows 20+ image domains including photos.zillowstatic.com, ap.rdcpix.com, ssl.cdn-redfin.com. These are third-party listing images with no size/format control. Without next/image optimization, these load at original resolution.
PERF-005 · Elasticsearch query patterns No query result caching is documented. Elasticsearch full-text property searches run on each user query. For high-traffic demo scenarios, this is a cold-hit bottleneck.
Optimization Opportunities
| ID | Opportunity | Effort | Impact |
|---|---|---|---|
| OPT-001 | Dynamic import Mapbox components with ssr: false | Low | High — eliminates SSR failure risk |
| OPT-002 | Add Redis/Upstash cache for Elasticsearch results | Medium | High — reduces ES load under demo traffic |
| OPT-003 | Stream all LLM analysis routes using Vercel AI SDK | Medium | High — eliminates long TTFB on analysis routes |
| OPT-004 | Remove @googlemaps/js-api-loader if only static images are needed | Low | Medium — simplifies bundle |
| OPT-005 | Add next/image width/height hints for listing photos | Low | Medium — reduces CLS and bandwidth |
| OPT-006 | Instrument cold start times on LangGraph routes with OpenTelemetry | Low | Medium — enables data-driven optimization |
| OPT-007 | Singleton Elasticsearch client per serverless function lifecycle | Low | High — prevents connection exhaustion |
11. Immediate Action Priorities
Based on the current state, the following actions are highest value for the next development session:
- Merge PR #458 (theme persistence) — active UX regression affecting all users
- Remove
ignoreBuildErrors+ignoreDuringBuildsfromnext.config.tsand resolve surfaced errors — foundational correctness - Add Elasticsearch connection singleton to prevent serverless connection exhaustion under demo load
- Write integration test for freemium query gating (PR #455) before relying on it in demos
- Triage PR #396 (mobile) — either merge with known limitations or close and track separately
- Link
context/planning docs to active PRs — prevent knowledge fragmentation as codebase grows - Define AI route taxonomy — document which routes use AI SDK streaming vs. LangGraph agents to prevent inconsistent patterns
This document reflects repository state at merge of PR #464. Update after each sprint or major PR merge. Key signals to watch: PR #458 merge, TypeScript error count after removing build suppression, ES connection errors in staging logs.