hoangsonww/EstateWise-Chapel-Hill-Chatbot

Collaborative Collections (Saved Homes) - Shared Boards, Comments & Notifications

Aperta

#94 aperta il 3 ott 2025

 (2 commenti) (0 reazioni) (1 assegnatario)TypeScript (21 fork)auto 404
backendbugchoreci/cdcodexdocumentationduplicateenhancementextensionfrontendgood first issuehelp wantedquestiontesting

Metriche repository

Star
 (38 stelle)
Metriche merge PR
 (Metriche PR in attesa)

Descrizione

Summary

Add “Collections” so users can save homes (by ZPID), group them into shareable boards, discuss with comments, rank/prioritize, and get real-time updates and digests. Works for solo users and small groups (partner/agent). Integrates with Map, Chat, Insights, and Graph (Neo4j) for explainable “why this home is similar” callouts.

Motivation & Goals

  • Problem: Users currently discover properties but have no first-class way to save, organize, or collaborate on them inside EstateWise.

  • Goals:

    • Increase repeat usage and session length via saved content.
    • Enable collaborative decision-making (notes, comments, statuses).
    • Surface explainability via Neo4j edges on a board overview.
  • Success Metrics (30 days post-launch):

    • ≥30% of authenticated users create ≥1 collection.
    • Avg. homes per collection ≥5.
    • ≥25% of collections have ≥1 collaborator.
    • ≥15% reduction in time to “top pick” (measured by status changes / rank).

User Stories

  • As a guest, I can create a temporary collection in browser storage and later migrate it after sign-up.

  • As an authenticated user, I can:

    • Save a property from Chat, Map, and Property detail via “Save → Choose/New Collection”.
    • Organize items with status (Considering / Toured / Offer / Dropped), rank, tags, and notes.
    • Share a collection via invite (email link) with roles (Viewer/Commenter/Editor/Owner).
    • Comment on items and @mention collaborators.
    • See similarity reasons (same ZIP / neighborhood / similar-to) summarized per collection.
    • Get in-app notifications for comments/status changes, plus optional weekly digest.

Out of Scope (v1)

  • Agent scheduling/integrations (Calendly, etc.)
  • Push notifications on mobile (web push can be a follow-up)
  • Advanced RBAC beyond Viewer/Commenter/Editor/Owner

UX/IA

New routes

  • /collections (list + create)

  • /collections/:id (board view)

    • Left: board filters (status, tags), “Explain similarities”
    • Main: grid/list of cards (thumbnail, price/beds/baths, status, rank, tags, quick actions)
    • Right: activity feed (comments, joins, changes), board stats

Entry points

  • Map markers / property cards: “Save” button
  • Chat replies with ZPIDs: inline action “Save homes (3) to…” + “View on Map”
  • Insights: “Add selection to collection”

Components

  • SaveToCollectionDialog
  • CollectionCard, CollectionItemCard
  • CommentThread
  • BoardStatsPanel (with Chart.js)
  • SimilarityReasons (Neo4j badges)

Data Model (MongoDB)

// collections
{
  _id: ObjectId,
  ownerId: ObjectId,
  name: string,
  description?: string,
  visibility: 'private'|'shared',        // public later if needed
  members: [{ userId: ObjectId, role: 'viewer'|'commenter'|'editor'|'owner' }],
  createdAt: Date,
  updatedAt: Date
}

// collection_items
{
  _id: ObjectId,
  collectionId: ObjectId,
  zpid: string,
  addedBy: ObjectId,
  status: 'considering'|'toured'|'offer'|'dropped',
  rank?: number,                         // 1..n (unique per collection)
  tags?: string[],
  notes?: string,
  createdAt: Date,
  updatedAt: Date
}

// comments
{
  _id: ObjectId,
  collectionId: ObjectId,
  itemId: ObjectId,
  authorId: ObjectId,
  text: string,
  mentions?: ObjectId[],
  createdAt: Date
}

// invites
{
  _id: ObjectId,
  collectionId: ObjectId,
  email: string,
  role: 'viewer'|'commenter'|'editor',
  token: string,                         // signed, exp-bound
  expiresAt: Date,
  acceptedAt?: Date
}

Indexes

  • collection_items: { collectionId: 1, rank: 1 }, { collectionId: 1, zpid: 1 }, { addedBy: 1, createdAt: -1 }
  • comments: { collectionId: 1, itemId: 1, createdAt: -1 }
  • invites: { collectionId: 1, email: 1 }, { token: 1 } (unique)

REST Endpoints (Express)

POST   /api/collections
GET    /api/collections              // mine + shared-with-me
GET    /api/collections/:id
PUT    /api/collections/:id
DELETE /api/collections/:id

POST   /api/collections/:id/items
GET    /api/collections/:id/items
PUT    /api/collections/:id/items/:itemId
DELETE /api/collections/:id/items/:itemId

POST   /api/collections/:id/comments
GET    /api/collections/:id/comments?itemId=...

POST   /api/collections/:id/invites
POST   /api/collections/invites/accept   // body: { token }
DELETE /api/collections/:id/members/:userId

GET    /api/collections/:id/similarity   // summarize Neo4j reasons for items
GET    /api/collections/:id/stats        // counts by status, price hist, etc.

tRPC (examples)

collections.create, collections.listMine, collections.get, collections.update, collections.remove
collections.addItem, collections.listItems, collections.updateItem, collections.removeItem
collections.addComment, collections.listComments
collections.invite, collections.acceptInvite, collections.removeMember
collections.similarity, collections.stats

Neo4j Integration

  • For each item’s zpid, fetch graph context:

    • (:Property {zpid})-[:IN_NEIGHBORHOOD|IN_ZIP|SIMILAR_TO]->(:Property ...)
  • API aggregates per-collection:

    • “Top 3 similarity clusters” (neighborhood/zip)
    • Count of items connected via SIMILAR_TO
  • Fallback: if Neo4j disabled, the endpoint returns 503 and UI hides badges gracefully (consistent with current graph behavior).

Realtime & Notifications

  • Realtime: Socket.IO or tRPC WebSockets for:

    • new comment, status change, member added
  • In-app notifications: bell icon + unread count, persisted in Mongo.

  • Weekly digest (optional, feature flag): background job (cron/Cloud Run) emails board summary & changes (SendGrid/Postmark).

Security & Privacy

  • All endpoints require JWT auth; collection membership enforced server-side.
  • Invite tokens are signed, short-lived; role cannot exceed inviter’s role.
  • Rate-limit comment creation; HTML-escape text; allow safe Markdown subset.

Performance

  • Redis cache for collections.stats (TTL short, e.g., 60s) and similarity summaries (TTL 5 min).
  • Batch Neo4j calls per board.
  • Paginate items and comments.

Telemetry

  • Events: collection_created, item_added, status_updated, comment_added, member_invited, invite_accepted, similarity_viewed.
  • Prometheus: counters + latency histograms per endpoint.

Rollout Plan

  1. Behind feature flag (FEATURE_COLLECTIONS=true) for staff.
  2. Internal test → limited beta (5–10% of authenticated users) → 100%.
  3. Backfill/migration: none needed.
  4. Add “What’s New” toast linking to /collections.

Acceptance Criteria

  • Create/list/get/update/delete collections behind auth.
  • Save from Map and Chat adds the right ZPIDs to chosen collection.
  • Commenting works with @mentions and realtime updates.
  • Sharing via invite link assigns correct role; role enforcement verified.
  • Board shows status filters, tags, ranking, and basic stats (counts, price histogram).
  • Similarity panel renders when Neo4j is enabled; hidden (no errors) when disabled.
  • In-app notifications for comments and status changes.
  • E2E tests cover main flows (create, save, share, comment).

Open Questions

  • Should guests be able to export a collection to CSV/PDF without sign-up?
  • Allow public, read-only link for agents to share externally?
  • Do we need per-item attachments (e.g., tour photos/notes) in v1?

Task Breakdown

Backend

  • Schemas + indexes (Mongo)
  • Controllers/routes (REST) + tRPC routers
  • Role guard middleware (Owner/Editor/Commenter/Viewer)
  • Invite token service (sign/verify/expire)
  • Similarity aggregation using Neo4j (feature-flagged)
  • Notifications service (+Redis pub/sub if using Socket.IO)
  • Tests: unit (Jest) + integration

Frontend (Next.js/React, Shadcn, Tailwind, Framer Motion)

  • Collections list page
  • Board view (grid/list, filters, stats, similarity panel)
  • SaveToCollectionDialog (Map/Chat entry points)
  • CommentThread with @mentions
  • Share/invite UI with role picker
  • In-app notifications UI
  • Tests: unit + RTL + Cypress e2e

DevOps

  • Env flags: FEATURE_COLLECTIONS, INVITE_TOKEN_SECRET, DIGEST_EMAIL_ENABLED
  • CI: lint/test/build gates + new coverage thresholds
  • Observability: Prometheus metrics, dashboards updates
  • Docs: README, TECH_DOCS, Swagger (openapi), tRPC docs

Nice-to-Haves (stretch)

  • Weekly digest email (SendGrid/Postmark)
  • CSV/PDF export of board
  • Web push notifications

Estimated Effort

  • Backend: 3–5 days
  • Frontend: 5–8 days
  • QA/Docs/DevOps: 2–3 days (Small team, parallelized; stretch items excluded.)

Risks & Mitigations

  • Data growth (comments/items): indexes + pagination; prune old notifications.
  • Permission bugs: centralize role checks; add integration tests.
  • Neo4j latency: batch queries; cache summaries.

Guida contributor