@happyvertical/smrt-places 0.57.36 → 0.57.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,13 +3,13 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-places",
6
- "packageVersion": "0.57.36",
6
+ "packageVersion": "0.57.37",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "d70331d1b4596cf6e9f7b2d2611d0ff8f277dfd63b5aaae7d766d50cfbe413a1",
11
- "packageJson": "a1f801ab278eed4f208cd899828d881386ac0fe66073a9c16f212236da5ed75c",
12
- "agents": "1f12a465f3ef103ac0ba27bcec1ec2b982fd0f5e8a63b9a42738f2c79ecebe49"
10
+ "manifest": "d7701265ab3b7339a8c9f52ca524d49abc195c004f98ec49bde076f5bc62bd28",
11
+ "packageJson": "49012c674d84ea10fde9b440950d1069e82b0887c36a56663c3b716e7521a9cd",
12
+ "agents": "8b7e9c23fd1311b3d04afe693969c1caaaa5d166e436f48e70c3504efbbadce9"
13
13
  },
14
14
  "exports": [
15
15
  ".",
@@ -695,91 +695,106 @@
695
695
  "type": "foreignKey",
696
696
  "required": false,
697
697
  "related": "PlaceType",
698
- "columnType": "UUID"
698
+ "columnType": "UUID",
699
+ "description": "What kind of place this is, such as a building, a room or a storage zone."
699
700
  },
700
701
  {
701
702
  "name": "name",
702
703
  "type": "text",
703
704
  "required": false,
704
- "columnType": "TEXT"
705
+ "columnType": "TEXT",
706
+ "description": "What the place is called, such as \"Main warehouse\" or \"Aisle 4\"."
705
707
  },
706
708
  {
707
709
  "name": "description",
708
710
  "type": "text",
709
711
  "required": false,
710
- "columnType": "TEXT"
712
+ "columnType": "TEXT",
713
+ "description": "A few words about the place and what happens there."
711
714
  },
712
715
  {
713
716
  "name": "latitude",
714
717
  "type": "decimal",
715
718
  "required": false,
716
- "columnType": "REAL"
719
+ "columnType": "REAL",
720
+ "description": "How far north or south the place is on a map. Leave empty for a place that is not on a map."
717
721
  },
718
722
  {
719
723
  "name": "longitude",
720
724
  "type": "decimal",
721
725
  "required": false,
722
- "columnType": "REAL"
726
+ "columnType": "REAL",
727
+ "description": "How far east or west the place is on a map. Leave empty for a place that is not on a map."
723
728
  },
724
729
  {
725
730
  "name": "streetNumber",
726
731
  "type": "text",
727
732
  "required": false,
728
- "columnType": "TEXT"
733
+ "columnType": "TEXT",
734
+ "description": "The number of the building on its street."
729
735
  },
730
736
  {
731
737
  "name": "streetName",
732
738
  "type": "text",
733
739
  "required": false,
734
- "columnType": "TEXT"
740
+ "columnType": "TEXT",
741
+ "description": "The name of the street the place is on."
735
742
  },
736
743
  {
737
744
  "name": "city",
738
745
  "type": "text",
739
746
  "required": false,
740
- "columnType": "TEXT"
747
+ "columnType": "TEXT",
748
+ "description": "The town or city the place is in."
741
749
  },
742
750
  {
743
751
  "name": "region",
744
752
  "type": "text",
745
753
  "required": false,
746
- "columnType": "TEXT"
754
+ "columnType": "TEXT",
755
+ "description": "The state, province or region the place is in."
747
756
  },
748
757
  {
749
758
  "name": "country",
750
759
  "type": "text",
751
760
  "required": false,
752
- "columnType": "TEXT"
761
+ "columnType": "TEXT",
762
+ "description": "The country the place is in."
753
763
  },
754
764
  {
755
765
  "name": "postalCode",
756
766
  "type": "text",
757
767
  "required": false,
758
- "columnType": "TEXT"
768
+ "columnType": "TEXT",
769
+ "description": "The postal or zip code of the address."
759
770
  },
760
771
  {
761
772
  "name": "countryCode",
762
773
  "type": "text",
763
774
  "required": false,
764
- "columnType": "TEXT"
775
+ "columnType": "TEXT",
776
+ "description": "The short two-letter code for the country, such as CA or US."
765
777
  },
766
778
  {
767
779
  "name": "timezone",
768
780
  "type": "text",
769
781
  "required": false,
770
- "columnType": "TEXT"
782
+ "columnType": "TEXT",
783
+ "description": "The time zone the place keeps, such as America/Toronto."
771
784
  },
772
785
  {
773
786
  "name": "externalId",
774
787
  "type": "text",
775
788
  "required": false,
776
- "columnType": "TEXT"
789
+ "columnType": "TEXT",
790
+ "description": "The reference the map provider uses for this place, filled in when the app looks it up."
777
791
  },
778
792
  {
779
793
  "name": "source",
780
794
  "type": "text",
781
795
  "required": false,
782
- "columnType": "TEXT"
796
+ "columnType": "TEXT",
797
+ "description": "Which map provider the place was looked up from, if any."
783
798
  },
784
799
  {
785
800
  "name": "metadata",
@@ -1384,13 +1399,15 @@
1384
1399
  "type": "text",
1385
1400
  "required": true,
1386
1401
  "columnType": "TEXT",
1387
- "default": ""
1402
+ "default": "",
1403
+ "description": "The name of the kind of place, such as \"Building\", \"Room\" or \"Zone\"."
1388
1404
  },
1389
1405
  {
1390
1406
  "name": "description",
1391
1407
  "type": "text",
1392
1408
  "required": false,
1393
- "columnType": "TEXT"
1409
+ "columnType": "TEXT",
1410
+ "description": "A few words about when to use this kind of place."
1394
1411
  },
1395
1412
  {
1396
1413
  "name": "createdAt",
@@ -1936,7 +1953,166 @@
1936
1953
  "polymorphicAssociations": 0,
1937
1954
  "uuidColumns": 18
1938
1955
  },
1939
- "agentDoc": "# @happyvertical/smrt-places\n\nHierarchical geographic database with organic growth via geocoding integration.\n\n## Models\n\n- **Place** (STI): hierarchical via `parentId`. Optional geo fields (all nullable — supports abstract places like game zones). `externalId`/`source` from geocoder. Metadata JSON.\n- **PlaceAsset**: dedicated owned-asset join in `place_assets` with `relationship` and `sortOrder`.\n- **PlaceType**: slug-based classification (country, city, building, zone, room, region).\n\n## Key Collection Methods\n\n| Method | Purpose |\n|--------|---------|\n| `lookupOrCreate(query)` | DB first → geocode if not found → create. Organic growth pattern. |\n| `findByCoordinates(lat, lng, threshold)` | Default 0.0001° ≈ 11m tolerance at equator |\n| `searchByProximity(lat, lng, radiusKm)` | Haversine distance, sorted by proximity |\n| `findWithGlobals(tenantId)` | Tenant + global (tenantId=null) places |\n| `getRootPlaces()`, `getByType(slug)` | Hierarchy + type queries |\n| `getAssets()` / `addAsset()` / `removeAsset()` | Owned asset helpers on both `Place` and `PlaceCollection`, backed by `place_assets` |\n\nHierarchy traversal: `getParent()`, `getChildren()`, `getAncestors()`, `getDescendants()`, `getHierarchy()`.\n\n## Gotchas\n\n- **Geo providers**: Google Maps needs `GOOGLE_MAPS_API_KEY`; OpenStreetMap is default\n- **Abstract places allowed**: lat/lng nullable — supports non-geographic locations\n- **Coordinate tolerance varies by latitude**: 0.0001° ≈ 11m at equator, less at poles\n- **Optional tenancy** with nullable tenantId\n",
1956
+ "agentDoc": "# @happyvertical/smrt-places\n\nHierarchical geographic database with organic growth via geocoding integration.\n\n## Models\n\n- **Place** (STI): hierarchical via `parentId`. Optional geo fields (all nullable — supports abstract places like game zones). `externalId`/`source` from geocoder. Metadata JSON.\n- **PlaceAsset**: dedicated owned-asset join in `place_assets` with `relationship` and `sortOrder`.\n- **PlaceType**: slug-based classification (country, city, building, zone, room, region).\n- **Recipe `places.locations`** (`src/recipes.ts`, help in `src/locations.recipe.md`): lists places and place types for the planner and other catalog hosts; `PlaceAsset` is closed and stays out. Fields it shows carry `@field({ description })` in plain words; `parentId` (inherited) is described by the recipe's `options` help. Keep both when editing the models.\n\n## Key Collection Methods\n\n| Method | Purpose |\n|--------|---------|\n| `lookupOrCreate(query)` | DB first → geocode if not found → create. Organic growth pattern. |\n| `findByCoordinates(lat, lng, threshold)` | Default 0.0001° ≈ 11m tolerance at equator |\n| `searchByProximity(lat, lng, radiusKm)` | Haversine distance, sorted by proximity |\n| `findWithGlobals(tenantId)` | Tenant + global (tenantId=null) places |\n| `getRootPlaces()`, `getByType(slug)` | Hierarchy + type queries |\n| `getAssets()` / `addAsset()` / `removeAsset()` | Owned asset helpers on both `Place` and `PlaceCollection`, backed by `place_assets` |\n\nHierarchy traversal: `getParent()`, `getChildren()`, `getAncestors()`, `getDescendants()`, `getHierarchy()`.\n\n## Gotchas\n\n- **Geo providers**: Google Maps needs `GOOGLE_MAPS_API_KEY`; OpenStreetMap is default\n- **Abstract places allowed**: lat/lng nullable — supports non-geographic locations\n- **Coordinate tolerance varies by latitude**: 0.0001° ≈ 11m at equator, less at poles\n- **Optional tenancy** with nullable tenantId\n",
1957
+ "recipes": [
1958
+ {
1959
+ "id": "places.locations",
1960
+ "className": "PlacesLocationsRecipe",
1961
+ "label": "Places",
1962
+ "summary": "Keep a list of the places your work happens, such as sites, buildings, rooms and storage zones, one inside another.",
1963
+ "synonyms": [
1964
+ "places",
1965
+ "locations",
1966
+ "sites",
1967
+ "buildings",
1968
+ "rooms",
1969
+ "addresses",
1970
+ "warehouses"
1971
+ ],
1972
+ "models": [
1973
+ "@happyvertical/smrt-places:Place",
1974
+ "@happyvertical/smrt-places:PlaceType"
1975
+ ],
1976
+ "nav": [
1977
+ {
1978
+ "label": "Places",
1979
+ "model": "@happyvertical/smrt-places:Place",
1980
+ "icon": "home",
1981
+ "description": "Every site, building, room and zone, with its address and what it is inside.",
1982
+ "noun": "place"
1983
+ },
1984
+ {
1985
+ "label": "Place types",
1986
+ "model": "@happyvertical/smrt-places:PlaceType",
1987
+ "icon": "tag",
1988
+ "description": "The kinds of place you keep, such as building or room.",
1989
+ "noun": "place type"
1990
+ }
1991
+ ],
1992
+ "requires": [],
1993
+ "section": {
1994
+ "id": "places",
1995
+ "label": "Locations",
1996
+ "icon": "home",
1997
+ "description": "The places your work happens."
1998
+ },
1999
+ "options": {
2000
+ "@happyvertical/smrt-places:Place": {
2001
+ "fields": {
2002
+ "name": {
2003
+ "order": 1
2004
+ },
2005
+ "typeId": {
2006
+ "label": "Type",
2007
+ "order": 2
2008
+ },
2009
+ "parentId": {
2010
+ "label": "Inside",
2011
+ "help": "The larger place this one is part of, such as the building a room is in.",
2012
+ "order": 3
2013
+ },
2014
+ "description": {
2015
+ "order": 4
2016
+ },
2017
+ "streetNumber": {
2018
+ "label": "Street number",
2019
+ "order": 5
2020
+ },
2021
+ "streetName": {
2022
+ "label": "Street name",
2023
+ "order": 6
2024
+ },
2025
+ "city": {
2026
+ "order": 7
2027
+ },
2028
+ "region": {
2029
+ "order": 8
2030
+ },
2031
+ "country": {
2032
+ "order": 9
2033
+ },
2034
+ "postalCode": {
2035
+ "label": "Postal code",
2036
+ "order": 10
2037
+ },
2038
+ "latitude": {
2039
+ "visibility": "advanced"
2040
+ },
2041
+ "longitude": {
2042
+ "visibility": "advanced"
2043
+ },
2044
+ "countryCode": {
2045
+ "label": "Country code",
2046
+ "visibility": "advanced"
2047
+ },
2048
+ "timezone": {
2049
+ "label": "Time zone",
2050
+ "visibility": "advanced"
2051
+ },
2052
+ "externalId": {
2053
+ "label": "Map reference",
2054
+ "visibility": "advanced"
2055
+ },
2056
+ "source": {
2057
+ "label": "Map provider",
2058
+ "visibility": "advanced"
2059
+ },
2060
+ "metadata": {
2061
+ "visibility": "hidden"
2062
+ },
2063
+ "tenantId": {
2064
+ "visibility": "hidden"
2065
+ },
2066
+ "createdAt": {
2067
+ "visibility": "hidden"
2068
+ },
2069
+ "updatedAt": {
2070
+ "visibility": "hidden"
2071
+ }
2072
+ }
2073
+ },
2074
+ "@happyvertical/smrt-places:PlaceType": {
2075
+ "fields": {
2076
+ "name": {
2077
+ "order": 1
2078
+ },
2079
+ "description": {
2080
+ "order": 2
2081
+ },
2082
+ "createdAt": {
2083
+ "visibility": "hidden"
2084
+ },
2085
+ "updatedAt": {
2086
+ "visibility": "hidden"
2087
+ }
2088
+ }
2089
+ }
2090
+ },
2091
+ "help": {
2092
+ "markdown": "## Overview\n\nPlaces is where you keep the sites, buildings, rooms and storage zones your\nwork happens in. Each place has a name, a type and, when it is somewhere real,\nan address. A place can sit inside a larger one, so a room belongs to a\nbuilding and a shelf to a room, and you can follow that chain either way. A\nplace does not have to be on a map: a storage zone or a work area with no\naddress is fine.\n\n## Tasks\n\n### Add a place\n\n1. Open the list of places and choose **New**.\n2. Type the **{field:Place.name}**, for example \"Main warehouse\".\n3. Pick its **{field:Place.typeId}**, such as building or room. Add a type first if the one you need is missing.\n4. Fill in the address: the **{field:Place.streetNumber}**, **{field:Place.streetName}**, **{field:Place.city}**, **{field:Place.region}**, **{field:Place.country}** and **{field:Place.postalCode}**. Leave these empty for a place that is not on a map.\n5. Save. When your app searches a map for a place, it can add the place for you with the address filled in from the map provider.\n\n### Put a place inside another\n\n1. Open the place and choose to edit it.\n2. In **{field:Place.parentId}**, pick the larger place it belongs to, such as the building a room is in.\n3. Save. The place now shows up under the one you chose.\n\n### Change or remove a place\n\n1. Open the place and choose to edit it.\n2. Change the **{field:Place.name}**, **{field:Place.description}** or address, then save.\n3. To remove a place you no longer use, open it and choose to delete it. Move anything inside it first.\n\n### Add a place type\n\n1. Open the list of place types and choose **New**.\n2. Type the **{field:PlaceType.name}**, for example \"Room\".\n3. Add a **{field:PlaceType.description}** so others know when to use it.\n4. Save. The type can now be picked when you add a place.\n",
2093
+ "fieldRefs": [
2094
+ "Place.city",
2095
+ "Place.country",
2096
+ "Place.description",
2097
+ "Place.name",
2098
+ "Place.parentId",
2099
+ "Place.postalCode",
2100
+ "Place.region",
2101
+ "Place.streetName",
2102
+ "Place.streetNumber",
2103
+ "Place.typeId",
2104
+ "PlaceType.description",
2105
+ "PlaceType.name"
2106
+ ]
2107
+ },
2108
+ "demo": {
2109
+ "mode": "server",
2110
+ "reasons": [
2111
+ "Needs a server because its package does not build for a browser: geo -> cache -> redis, node:zlib; url-signature node:crypto; and its package depends on @happyvertical/smrt-tenancy, which do not build for a browser (#3624, #3627)."
2112
+ ]
2113
+ }
2114
+ }
2115
+ ],
1940
2116
  "browser": {
1941
2117
  "status": "server-only",
1942
2118
  "issues": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-places",
3
- "version": "0.57.36",
3
+ "version": "0.57.37",
4
4
  "description": "Hierarchical place management with geo integration and SMRT framework support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -23,19 +23,19 @@
23
23
  "./manifest.json": "./dist/manifest.json"
24
24
  },
25
25
  "dependencies": {
26
- "@happyvertical/ai": "^0.109.0",
27
- "@happyvertical/cache": "^0.109.0",
28
- "@happyvertical/files": "^0.109.0",
29
- "@happyvertical/geo": "^0.109.0",
30
- "@happyvertical/logger": "^0.109.0",
31
- "@happyvertical/smrt-assets": "0.57.36",
32
- "@happyvertical/smrt-core": "0.57.36",
33
- "@happyvertical/smrt-tenancy": "0.57.36",
34
- "@happyvertical/sql": "^0.109.0",
35
- "@happyvertical/utils": "^0.109.0"
26
+ "@happyvertical/ai": "^0.110.0",
27
+ "@happyvertical/cache": "^0.110.0",
28
+ "@happyvertical/files": "^0.110.0",
29
+ "@happyvertical/geo": "^0.110.0",
30
+ "@happyvertical/logger": "^0.110.0",
31
+ "@happyvertical/smrt-assets": "0.57.37",
32
+ "@happyvertical/smrt-core": "0.57.37",
33
+ "@happyvertical/smrt-tenancy": "0.57.37",
34
+ "@happyvertical/sql": "^0.110.0",
35
+ "@happyvertical/utils": "^0.110.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@happyvertical/smrt-vitest": "0.57.36",
38
+ "@happyvertical/smrt-vitest": "0.57.37",
39
39
  "@types/node": "24.13.6",
40
40
  "typescript": "6.0.3",
41
41
  "vite": "8.1.6",