Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Building Data Codebook

Field-by-field reference for apps/frontend/src/data/buildingTypes.ts, buildings.json, and tags.tsx.

Building data tree

Where to find each piece of information on an exported Building object:

Building
├─ id                  string
├─ name                string
├─ media
│  ├─ mainImage        string
│  ├─ icon?            string
│  ├─ photos[]
│  │  ├─ link          string
│  │  └─ description   string
│  └─ floorPlans[]
│     ├─ link              string
│     ├─ description       string
│     ├─ category          "roomType" | "floor"
│     └─ virtualTourLink?  string
├─ amenities
│  ├─ roomTypes        RoomType[]
│  ├─ bathrooms
│  │  ├─ types         BathroomType[]
│  │  └─ details?      string
│  ├─ ac
│  │  ├─ level         ACLevel
│  │  └─ details?      string
│  ├─ kitchen
│  │  ├─ scope         KitchenScope
│  │  └─ details?      string
│  ├─ laundry
│  │  ├─ location      LaundryLocation
│  │  └─ details?      string
│  ├─ commonAreas
│  │  ├─ hasLounge     boolean
│  │  └─ details?      string
│  ├─ gym
│  │  ├─ available     boolean
│  │  └─ details?      string
│  └─ genderHousing    GenderHousing
├─ accessibility
│  ├─ wheelchairAccessible   boolean
│  ├─ serviceAnimalFriendly  boolean
│  ├─ groundFloorRooms       boolean
│  └─ strobeAlarm            boolean
├─ atmosphere
│  ├─ socialness?      number (1-5)
│  └─ noiseLevel?      number (1-5)
├─ location
│  ├─ latitude?        number
│  ├─ longitude?       number
│  ├─ closeBuildings[] string (building ids)
│  └─ note?            string
└─ editorialTags?[]    string

Enums

All enums below are plain numeric TypeScript enums (no explicit string values). The # column is the value stored in buildings.json and returned by the enum at runtime.

RoomType

#MemberMeaning
0TradSingleTraditional-style single, shared hallway bathroom.
1TradDoubleTraditional-style double, shared hallway bathroom.
2TradTripleTraditional-style triple, shared hallway bathroom.
3SemiSuiteSingleSemi-suite single, bathroom shared with an adjacent suite.
4SemiSuiteDoubleSemi-suite double, bathroom shared with an adjacent suite.
5SemiSuiteTripleSemi-suite triple, bathroom shared with an adjacent suite.
6SemiSuiteQuadSemi-suite, four occupants.
7ApartmentTripleApartment-style triple.
8StudioApartmentSingleStudio apartment, single occupant.
9StudioApartmentDoubleStudio apartment, two occupants.

BathroomType

#MemberMeaning
0CommunalShared per floor/wing, traditional style.
1SharedSuiteShared with one adjacent suite, semi-suite style.
2PrivateTruly en-suite / in-room, apartment style only.

ACLevel

#MemberMeaning
0NoneNo AC.
1ByNecessityAccommodation, triple, or lottery-only AC.
2WindowWindow units, not central.
3CentralFull central AC.

LaundryLocation

#MemberMeaning
0NoneNo laundry.
1BasementBasement only.
2EachFloorLaundry on every floor.
3InUnitIn-unit washer/dryer.

KitchenScope

#MemberMeaning
0NoneNo kitchen access.
1SharedCommunal, building or floor level; details says which.
2InUnitKitchenette in the room (“en suite kitchen”).

Floor-vs-building distinctions for Shared live in the details string, not as a separate enum value.

GenderHousing

#MemberMeaning
0CoEdCo-ed housing.
1WomenOnlyWomen only.
2MenOnlyMen only.
3GenderInclusiveGender-inclusive housing.

“Value + details” wrapper pattern

Bathrooms, AirConditioning, Kitchen, Laundry, CommonAreas, Gym all follow one pattern: a comparable/filterable value (enum, array, or boolean) plus an optional details string for a freeform human blurb. Every attribute that needs to be both compared and described gets this shape.

  • Bathrooms.types is an array so a building with more than one bathroom style lists all of them.
  • CommonAreas.hasLounge backs the “Common areas” filter.
  • Gym.available is a plain boolean for filtering; details carries the description.

Grouped types

  • AmenityData holds everything the filter/survey/comparison UI reads: room types, bathrooms, AC, kitchen, laundry, common areas, gym, gender housing.
  • Accessibility holds wheelchairAccessible, serviceAnimalFriendly, groundFloorRooms, strobeAlarm (strobe fire alarm & doorbell). Filled in per building as data becomes available.
  • Atmosphere holds socialness / noiseLevel, 1-5 scales matching the survey sliders and review table. Both are optional since a building may not have data yet.
  • Location holds latitude/longitude for a “distance from landmark” filter (no distance value is stored on the building itself), closeBuildings (a list of building ids for the “Closest Buildings” detail card), and an optional note for a human-written blurb.
  • GalleryImage is link + description, one per photo.
  • FloorPlan is link + description + category ("roomType" | "floor") + optional virtualTourLink, which points to a walkthrough for that specific floor plan.
  • Media holds mainImage, optional icon, photos[], and floorPlans[].
  • Building is the top-level shape: id, name, media, amenities, accessibility, atmosphere, location, and optional editorialTags for hand-authored tags with no structured source.

Filter scoring

scoreBuilding in scoring.ts scores a building against the filter panel. Set controls add points; missing data adds nothing and never subtracts:

Filter controlScored from
Air conditioningamenities.ac.level is Window or Central
Laundry on each flooramenities.laundry.location is EachFloor
En suite bathroomamenities.bathrooms.types has SharedSuite or Private
Single roomamenities.roomTypes has a single-occupant type
Service Animalaccessibility.serviceAnimalFriendly
Wheelchair accessibleaccessibility.wheelchairAccessible
Socialness, Noise Levelatmosphere.socialness, atmosphere.noiseLevel
Distance fromlocation.closeBuildings on either building

atmosphere, coordinates, and accessibility flags are empty so those score 0. groupBuildings sorts by score into bestFit, decentFit, and wildCard, three per row.

Tag derivation

deriveTags(building) in tags.tsx computes a building’s tag ids from its structured fields, so a tag can never drift out of sync with the data it is based on:

Tag idDerived from
noKitchenamenities.kitchen.scope === KitchenScope.None
limitedACamenities.ac.level === ACLevel.ByNecessity
noCentralACamenities.ac.level is neither None nor Central
basementLaundryamenities.laundry.location === LaundryLocation.Basement
gymAccessamenities.gym.available
girlsOnlyamenities.genderHousing === GenderHousing.WomenOnly
lgbtqInclusiveamenities.genderHousing === GenderHousing.GenderInclusive

editorialTags on a building are appended as-is, for a tag with no structured backing.

Data loading

buildings.ts imports buildings.json and casts it to Building[]. buildingTypes.ts holds every type and enum above, and is the single import source for the context, filter, survey, and comparison consumers.