No updates detected yet. GitHub releases will appear here.
Community-driven coffee discovery platform with geospatial search, verification, and location-aware features.
翻訳待ち
Loading the full README. The saved excerpt is shown below.
A map for remembering the cup you liked, and finding the next coffee and the beans to take home.
Version 1 promised "an app for saving independent cafes." Google Maps and Naver already do that, with more data and a decade of head start. Saving a place is not a problem anyone had.
The version 2 promise is narrower and, so far, unclaimed:
Remember the cup you liked. Find the next coffee, and the beans to take home.
That reframing changed the data model, the map, the badges and the onboarding, because the unit of value moved from a place you saved to a coffee you drank.Read the full README ↗Version 1 promised "an app for saving independent cafes." Google Maps and Naver already do that, with more data and a decade of head start. Saving a place is not a problem anyone had.
The version 2 promise is narrower and, so far, unclaimed:
Remember the cup you liked. Find the next coffee, and the beans to take home.
That reframing changed the data model, the map, the badges and the onboarding, because the unit of value moved from a place you saved to a coffee you drank.
Someone local who tries new coffee and buys beans when they like one. Coffee knowledge is not an entry requirement. Early users are picked by a recent decision they struggled with, not by "likes coffee" as an interest.
Daily opens are not a goal. Consumption frequency and app frequency are different problems: someone who drinks the same beans every morning has no reason to log it every morning. Notifications and streak badges can force the number up. This bets on being the thing that comes to mind in those three moments instead.
The promise is completeness, not density:
Every place in KW where you can buy beans is here.
A small pool is why this market was chosen: it is the only size where auditing every cafe by hand over two weekends is realistic. It is also a university town, so every September and January regenerates a cohort of people who just moved and do not know where the coffee is. Ontario expansion waits until KW is proven; the seed script already carries the bounding box.
Completeness is measured against a stricter set than "places that serve coffee": a cafe is listed only if it is coffee-forward, meaning it can name the roaster of what it pours and coffee is the point of the visit. Holding KW to that bar took the hand-reviewed map from 64 cafes to 39. The rubric is in cafe curation.
A cup leaves a ring on the table, and that ring is the oldest proof of a visit there is. The line starts heavier at two o'clock where the cup lands, travels around and pools at the bottom the way coffee does, then turns inward into the crease of a coffee bean: the place you visited becomes the coffee you drank. The ring never closes, because there is always a next place. The drop outside the opening is the bean you drop when you log a cup, and it doubles as the dot of the i, because the record is yours.
One drawing is used at every size, from the 1024px export to the 32px header, in one flat colour: brand brown on light grounds, cream on dark ones. The app icon, favicons and web manifest icons are all cut from it.
Each one lists what was rejected, because that is where the reasoning lives.
| Decision | Why | Rejected |
|---|---|---|
| A log is an experience; the bean is optional | "I drank this here, liked it, bought the bag" is one record. Requiring origin, process and price to create a bean makes the first log a chore | Bean as the unit of record, with a mandatory catalogue entry before you can log anything |
| A cafe's bean list is derived from public logs | One source of truth, and it can never expose more than the author chose to show | A cafe_bean_offerings table fed automatically by every log, which would have leaked who drank what from private and anonymous entries |
| Trait claims need evidence or a queue | Registering means passing a 100m check while standing there; a purchase logged inside the shop means the same check plus having bought the bag. Those write straight through. Everything else waits for review | Trusting every button press on a cafe page, and a review queue nobody drains |
| Franchise filtering reads OpenStreetMap, not a brand list | A hardcoded blocklist stops working the moment you cross a border. Name counting misfires: a global count flags the Toronto cafe "The Link" as a 217-location chain | Maintaining a blocklist by hand, and matching on names |
| Cafe identity is borrowed, not invented | A cafe is the OSM node id or Google place id it already has, each under a partial UNIQUE index | Generating an internal identity and reconciling duplicates later |
| Unclassifiable venues are listed, not rejected | A wrong rejection is invisible to everyone, including the operator. A wrong listing shows up in the review queue | Failing closed on the classifier |
| Listing means coffee-forward, not coffee-serving | A four-tier rubric: own roastery, multi-roaster cafe, espresso and filter bar are listed; tier 4 is defined only as a cafe that cannot name its roaster, so a dessert-first shop that pours a named roaster is listed. Each listed tier is backed by a trait with a dated observation, so tiers are a reviewer's shorthand and never stored | A stored tier column that could disagree with the traits; cutting "too much of a dessert shop", which no two reviewers would draw in the same place; equipment and barista-process fields that nobody outside the bar can verify |
| Badges count coming back | Ranking who arrived first rewards the calendar, not the coffee | The 1.x pioneer system (Navigator, Scout), removed in the pivot |
This is the beginning of the README. Read the rest at the original. Read the full README ↗