01
挑战
咖啡发现应用要么是毫无灵魂的目录,要么是封闭的点评孤岛。我想围绕巴黎的咖啡文化打造一个真正的社交产品——关注、动态、共享清单、Top 3 排名——并独自完成所有环节:设计、移动开发、后端、推送通知、商店上架和数据分析。难点在于产品覆盖面:登录(Apple/Google)、带聚合的交互地图、实时动态、审核工具、深度链接以及能促进转化的访客模式。
02
解决方案
采用 React Native + Expo(通过 Expo Router 实现文件路由)开发,后端基于 Supabase:Postgres 行级安全、存储、RPC 和认证触发器。React Query 负责动态、点评、清单和关注的缓存与乐观更新。地图通过 supercluster 聚合数百家咖啡馆,个人主页展示 Top 3 领奖台和可分享清单,权益系统以滑动领取的方式回馈早期会员。通过 EAS 发布至双商店,接入 PostHog 和 Sentry,支持法语/英语,并配有通用链接和每家咖啡馆的公开网页。
typescript
// Map clustering — rebuild index only when cafés change,
// re-query clusters when the visible region moves
export function useClusters({ cafes, region, radius = 60 }: Options) {
const index = useMemo(() => {
if (!cafes?.length) return null;
const sc = new Supercluster<PointProps, ClusterProps>({
radius,
maxZoom: 16,
minPoints: 3,
});
sc.load(
cafes.map((cafe) => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: [cafe.longitude, cafe.latitude],
},
properties: { cafe },
}))
);
return sc;
}, [cafes, radius]);
const clusters = useMemo(() => {
if (!index || !region) return [];
const zoom = Math.round(Math.log2(360 / region.latitudeDelta));
return index.getClusters(regionToBbox(region), zoom);
}, [index, region]);
return { clusters, index };
}↳ 基于 Supercluster 的地图聚合 hook — 仅在咖啡馆列表变化时重建索引,地图移动只触发低成本的 bbox 重新查询





