From b51fef14fd89176f418ebb6b2daf75882ac8b765 Mon Sep 17 00:00:00 2001
From: Stan Runge
Date: Sat, 24 Oct 2026 14:07:33 +0000
Subject: [PATCH] houses: nightly Kamernet + Vesteda scraper, dedupe by
address, owner-only /trackers/houses
- scripts/house-scrape.ts: polite nightly scrape (honest UA, 6-10 s apart, stops a source on 403/challenge), ingest + price history + removals, ntfy alerts on a separate topic (max 5 + summary, first run seeds)
- address_key + duplicate_of: copies on another source link to one listing, manual wins
- /projects/house-tracker -> /trackers/houses (308), owner only (404 otherwise); filters for min m2, rooms, source, Gouda region default; notes, add-by-hand form, total rent, also-on links
- scripts/house-db.sh: run the house-listing CLI as the limited house_cli role
- deploy/systemd/house-scrape.{service,timer}
---
deploy/systemd/house-scrape.service | 13 +
deploy/systemd/house-scrape.timer | 10 +
docs/house-tracker.md | 33 +-
.../migration.sql | 5 +
.../snapshot.json | 16755 ++++++++++++++++
scripts/house-db.sh | 12 +
scripts/house-scrape.ts | 282 +
src/lib/house-tracker/address.test.ts | 28 +
src/lib/house-tracker/address.ts | 104 +
.../fixtures/kamernet-search-gouda.html | 1 +
.../fixtures/vesteda-search-gouda.json | 190 +
src/lib/house-tracker/ingest.ts | 124 +
src/lib/house-tracker/kamernet.ts | 81 +
src/lib/house-tracker/scraped.ts | 43 +
src/lib/house-tracker/scrapers.test.ts | 64 +
src/lib/house-tracker/vesteda.ts | 94 +
src/lib/projects.ts | 15 +-
src/lib/server/db/schema/house-tracker.ts | 18 +-
src/lib/server/owner.test.ts | 2 +
src/lib/server/owner.ts | 2 +
.../house-tracker/[...rest]/+server.ts | 10 +
src/routes/trackers/houses/+layout.server.ts | 10 +
.../houses}/+page.server.ts | 176 +-
.../houses}/+page.svelte | 105 +-
24 files changed, 18142 insertions(+), 35 deletions(-)
create mode 100644 deploy/systemd/house-scrape.service
create mode 100644 deploy/systemd/house-scrape.timer
create mode 100644 drizzle/20261024140745_house_scrapers/migration.sql
create mode 100644 drizzle/20261024140745_house_scrapers/snapshot.json
create mode 100755 scripts/house-db.sh
create mode 100644 scripts/house-scrape.ts
create mode 100644 src/lib/house-tracker/address.test.ts
create mode 100644 src/lib/house-tracker/address.ts
create mode 100644 src/lib/house-tracker/fixtures/kamernet-search-gouda.html
create mode 100644 src/lib/house-tracker/fixtures/vesteda-search-gouda.json
create mode 100644 src/lib/house-tracker/ingest.ts
create mode 100644 src/lib/house-tracker/kamernet.ts
create mode 100644 src/lib/house-tracker/scraped.ts
create mode 100644 src/lib/house-tracker/scrapers.test.ts
create mode 100644 src/lib/house-tracker/vesteda.ts
create mode 100644 src/routes/projects/house-tracker/[...rest]/+server.ts
create mode 100644 src/routes/trackers/houses/+layout.server.ts
rename src/routes/{projects/house-tracker => trackers/houses}/+page.server.ts (61%)
rename src/routes/{projects/house-tracker => trackers/houses}/+page.svelte (78%)
diff --git a/deploy/systemd/house-scrape.service b/deploy/systemd/house-scrape.service
new file mode 100644
index 0000000..64a6b7d
--- /dev/null
+++ b/deploy/systemd/house-scrape.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=House tracker nightly scrape (Kamernet, Vesteda -> house.listings)
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=oneshot
+# A checkout of stan/website on main. Not the live dev tree.
+WorkingDirectory=%h/dev/website-houses
+# DB_URL (house_scraper role: house schema only), optional HOUSE_NTFY_URL; mode 600, never committed.
+EnvironmentFile=%h/.config/house-scrape.env
+ExecStart=/usr/bin/bun scripts/house-scrape.ts
+TimeoutStartSec=900
diff --git a/deploy/systemd/house-scrape.timer b/deploy/systemd/house-scrape.timer
new file mode 100644
index 0000000..1816327
--- /dev/null
+++ b/deploy/systemd/house-scrape.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=House tracker scrape, once a night
+
+[Timer]
+OnCalendar=*-*-* 03:40:00 Europe/Amsterdam
+RandomizedDelaySec=1200
+Persistent=true
+
+[Install]
+WantedBy=timers.target
diff --git a/docs/house-tracker.md b/docs/house-tracker.md
index 1807b87..ec1f1d7 100644
--- a/docs/house-tracker.md
+++ b/docs/house-tracker.md
@@ -1,7 +1,38 @@
# House tracker
+## Nightly scrape on stan-vm (2026-10)
+
+`scripts/house-scrape.ts` runs once a night from a systemd user timer
+(`deploy/systemd/house-scrape.{service,timer}`, 03:40 Amsterdam + up to 20 min jitter) and
+writes `house.listings` directly with the limited `house_scraper` role
+(`~/.config/house-scrape.env`, mode 600). One request at a time, 6–10 s apart, honest
+User-Agent, robots.txt-allowed paths only. A 403/429/challenge stops that source for the
+night and is logged as `challenged`; nothing is retried or worked around.
+
+| source | how | status |
+| ---------------------- | ------------------------------------------------------------- | ------------------------------------ |
+| Kamernet | `/huren/huurwoningen-` pages, `__NEXT_DATA__` JSON | scraped (10 cities around Gouda) |
+| Vesteda | `POST /api/units/search/facet` (what their site calls), 20 km | scraped; rented units count as gone |
+| Pararius | Cloudflare 403 from the Hetzner IP | not scraped here; home worker below |
+| huurwoningen.nl | same Cloudflare 403 (Pararius group) | skipped |
+| Funda | bot-check page ("Je bent bijna op de pagina…") | skipped |
+| Huurstunt | Cloudflare challenge | skipped |
+| Mijndak Midden-Holland | OutSystems app behind a login, no public listing feed | skipped; use their own e-mail alerts |
+
+Same home on two sources: `address_key` (street + number + city, normalised, see
+`src/lib/house-tracker/address.ts`) links the copy to the original via `duplicate_of`; a
+manual entry wins. The page shows one row with "also on …" links. Kamernet never shows house
+numbers, so its listings are never merged. Alerts: new non-copy listings matching an alert
+rule go to `HOUSE_NTFY_URL` (its own topic, max 5 per night plus one summary); the first run
+of a source only seeds.
+
+Manual listings: `scripts/house-listing.ts` (CLI) or the form on the page. Against prod use
+`scripts/house-db.sh …`, which runs the CLI as `house_cli` (SELECT/INSERT/UPDATE/
+DELETE on house.listings, SELECT/INSERT on house.price_history, nothing else) from
+`~/.config/house-cli.env`.
+
Personal tool: collects Dutch housing listings into Postgres, shows them on
-`/projects/house-tracker` (admin only) and sends an alert when a new listing
+`/trackers/houses` (owner only, 404 for everyone else; the old URL redirects) and sends an alert when a new listing
matches a rule. Only Pararius for now; other sources plug in the same way.
## How it fits together
diff --git a/drizzle/20261024140745_house_scrapers/migration.sql b/drizzle/20261024140745_house_scrapers/migration.sql
new file mode 100644
index 0000000..5e52d6a
--- /dev/null
+++ b/drizzle/20261024140745_house_scrapers/migration.sql
@@ -0,0 +1,5 @@
+ALTER TABLE "house"."listings" ADD COLUMN "address_key" text;--> statement-breakpoint
+ALTER TABLE "house"."listings" ADD COLUMN "duplicate_of" integer;--> statement-breakpoint
+ALTER TABLE "house"."listings" ADD COLUMN "total_price_eur" integer;--> statement-breakpoint
+CREATE INDEX "listings_address_idx" ON "house"."listings" ("address_key") WHERE address_key IS NOT NULL;--> statement-breakpoint
+ALTER TABLE "house"."listings" ADD CONSTRAINT "listings_duplicate_of_listings_id_fkey" FOREIGN KEY ("duplicate_of") REFERENCES "house"."listings"("id") ON DELETE SET NULL;
\ No newline at end of file
diff --git a/drizzle/20261024140745_house_scrapers/snapshot.json b/drizzle/20261024140745_house_scrapers/snapshot.json
new file mode 100644
index 0000000..b712593
--- /dev/null
+++ b/drizzle/20261024140745_house_scrapers/snapshot.json
@@ -0,0 +1,16755 @@
+{
+ "version": "8",
+ "dialect": "postgres",
+ "id": "511535e1-3a09-4cf2-8cc5-c25ce091e6be",
+ "prevIds": [
+ "fe485ab8-9b4d-491e-b4fb-4c2d3933e6e5"
+ ],
+ "ddl": [
+ {
+ "name": "animaldex",
+ "entityType": "schemas"
+ },
+ {
+ "name": "auth",
+ "entityType": "schemas"
+ },
+ {
+ "name": "books",
+ "entityType": "schemas"
+ },
+ {
+ "name": "cs",
+ "entityType": "schemas"
+ },
+ {
+ "name": "games",
+ "entityType": "schemas"
+ },
+ {
+ "name": "groceries",
+ "entityType": "schemas"
+ },
+ {
+ "name": "health",
+ "entityType": "schemas"
+ },
+ {
+ "name": "house",
+ "entityType": "schemas"
+ },
+ {
+ "name": "meta",
+ "entityType": "schemas"
+ },
+ {
+ "name": "money",
+ "entityType": "schemas"
+ },
+ {
+ "name": "ref",
+ "entityType": "schemas"
+ },
+ {
+ "name": "site",
+ "entityType": "schemas"
+ },
+ {
+ "name": "tasks",
+ "entityType": "schemas"
+ },
+ {
+ "values": [
+ "draft",
+ "published"
+ ],
+ "name": "blog_article_status",
+ "entityType": "enums",
+ "schema": "site"
+ },
+ {
+ "values": [
+ "catchable",
+ "trade_only",
+ "transfer_only",
+ "event_only",
+ "unknown",
+ "evolve",
+ "breed"
+ ],
+ "name": "availability",
+ "entityType": "enums",
+ "schema": "ref"
+ },
+ {
+ "values": [
+ "pending",
+ "matched",
+ "low_confidence",
+ "not_found",
+ "manual"
+ ],
+ "name": "metadata_status",
+ "entityType": "enums",
+ "schema": "books"
+ },
+ {
+ "values": [
+ "want_to_read",
+ "reading",
+ "finished",
+ "abandoned"
+ ],
+ "name": "reading_status",
+ "entityType": "enums",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "account",
+ "entityType": "tables",
+ "schema": "auth"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "session",
+ "entityType": "tables",
+ "schema": "auth"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "user",
+ "entityType": "tables",
+ "schema": "auth"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "verification",
+ "entityType": "tables",
+ "schema": "auth"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "blog_articles",
+ "entityType": "tables",
+ "schema": "site"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tasks",
+ "entityType": "tables",
+ "schema": "site"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "task_topics",
+ "entityType": "tables",
+ "schema": "site"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "topics",
+ "entityType": "tables",
+ "schema": "site"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "catch_em_all_settings",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_games",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_encounters",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_evolutions",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_game_entries",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_locations",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "catch_em_all_entries",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "catch_em_all_games",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_games",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_items",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_progress",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "osu_entries",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_catches",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_dex_numbers",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_game_research",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_journeys",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_learnsets",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_milestones",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_moves",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_research",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "pokemon_seen",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_challenge_progress",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_challenges",
+ "entityType": "tables",
+ "schema": "ref"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_ranks",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tracker_weapon_ranks",
+ "entityType": "tables",
+ "schema": "games"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "animals",
+ "entityType": "tables",
+ "schema": "animaldex"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "sighting_photos",
+ "entityType": "tables",
+ "schema": "animaldex"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "sightings",
+ "entityType": "tables",
+ "schema": "animaldex"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "columns",
+ "entityType": "tables",
+ "schema": "meta"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "edit_log",
+ "entityType": "tables",
+ "schema": "meta"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tables",
+ "entityType": "tables",
+ "schema": "meta"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "accounts",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "bank_sessions",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "forecasts",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "insurances",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "projection_settings",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "recurring",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "transactions",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "utility_readings",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "utility_settings",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "wishlist",
+ "entityType": "tables",
+ "schema": "money"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "item_dimensions",
+ "entityType": "tables",
+ "schema": "cs"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "items",
+ "entityType": "tables",
+ "schema": "cs"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "price_observations",
+ "entityType": "tables",
+ "schema": "cs"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "price_streams",
+ "entityType": "tables",
+ "schema": "cs"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "alert_rules",
+ "entityType": "tables",
+ "schema": "house"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "listings",
+ "entityType": "tables",
+ "schema": "house"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "price_history",
+ "entityType": "tables",
+ "schema": "house"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "searches",
+ "entityType": "tables",
+ "schema": "house"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "worker_runs",
+ "entityType": "tables",
+ "schema": "house"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "appointments",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "body_measurements",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "medications",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "nutrition_daily",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "sleep",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "vaccinations",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "workouts",
+ "entityType": "tables",
+ "schema": "health"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "files",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "notes",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "progress",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "sessions",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "shelf_works",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "shelves",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "works",
+ "entityType": "tables",
+ "schema": "books"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "activity",
+ "entityType": "tables",
+ "schema": "tasks"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "areas",
+ "entityType": "tables",
+ "schema": "tasks"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "goals",
+ "entityType": "tables",
+ "schema": "tasks"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "tasks",
+ "entityType": "tables",
+ "schema": "tasks"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "groups",
+ "entityType": "tables",
+ "schema": "groceries"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "import_runs",
+ "entityType": "tables",
+ "schema": "groceries"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "item_prices",
+ "entityType": "tables",
+ "schema": "groceries"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "items",
+ "entityType": "tables",
+ "schema": "groceries"
+ },
+ {
+ "isRlsEnabled": false,
+ "name": "stores",
+ "entityType": "tables",
+ "schema": "groceries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "account_id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "issuer",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider_id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "access_token",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refresh_token",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id_token",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "access_token_expires_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "refresh_token_expires_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "scope",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "password",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expires_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "token",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ip_address",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_agent",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'user'",
+ "generated": null,
+ "identity": null,
+ "name": "role",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "email",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "email_verified",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "user"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "identifier",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "expires_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "content",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "tags",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "blog_article_status",
+ "typeSchema": "site",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'draft'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "current_points",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "total_points",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "tasks"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "task_id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "topic_id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "topics"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "topics"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "emoji",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "topics"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "topics"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "site",
+ "table": "topics"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_settings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_settings"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "generation",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "breeding",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_games"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "number",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "generation",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type1",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type2",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "hp",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "attack",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "defense",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "special_attack",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "special_defense",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "speed",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "evolves_from",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "evolution_chain",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "is_baby",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "is_legendary",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "is_mythical",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "location_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "area",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "method",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_level",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "max_level",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rarity",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "form",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "conditions",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pokeapi'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "from_pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "to_pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "method",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pokeapi'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "availability",
+ "typeSchema": "ref",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'catchable'",
+ "generated": null,
+ "identity": null,
+ "name": "availability",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pokeapi'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "region",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image_key",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image_credit",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pokeapi'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_locations"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_game_entry_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "franchise",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "short_name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "release_year",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rules",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_games"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "key",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "post_launch",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'done'",
+ "generated": null,
+ "identity": null,
+ "name": "milestone",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'osu'",
+ "generated": null,
+ "identity": null,
+ "name": "mode",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "beatmap_url",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "score_url",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pass'",
+ "generated": null,
+ "identity": null,
+ "name": "goal",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'stamina'",
+ "generated": null,
+ "identity": null,
+ "name": "skill",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bpm",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "duration",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "numeric",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accuracy",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "combo",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "misses",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "numeric",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pp",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'NM'",
+ "generated": null,
+ "identity": null,
+ "name": "mods",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "numeric(4,2)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1.00",
+ "generated": null,
+ "identity": null,
+ "name": "rate",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "achieved",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "played_on",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "nickname",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "level",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "moves",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "party_slot",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "shiny",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "nature",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ability",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ball",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "location",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'caught'",
+ "generated": null,
+ "identity": null,
+ "name": "obtained",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'story'",
+ "generated": null,
+ "identity": null,
+ "name": "stage",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "caught_on",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dex",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dex_name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "number",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_research"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "version_group",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_research"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "regions",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_game_research"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'story'",
+ "generated": null,
+ "identity": null,
+ "name": "stage",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "location",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "completed",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "version_group",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "moves",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "key",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'story'",
+ "generated": null,
+ "identity": null,
+ "name": "stage",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "done",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "power",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accuracy",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pp",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "priority",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "target",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_moves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_research"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "facts",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "pokemon_research"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pokemon_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "challenge_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "current",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "done",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "key",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "requirement",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reward",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "target",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source_url",
+ "entityType": "columns",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "game_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "level",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "prestige",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_id",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "1",
+ "generated": null,
+ "identity": null,
+ "name": "level",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "prestige",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "species",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "breed",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "animal_name",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ai_breed_suggestion",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ai_breed_confidence",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "submitted_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accepted_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "denied_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "animals"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sighting_id",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "r2_key",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "uploaded_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "animal_id",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reporter_name",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "seen_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lat",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lng",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "submitted_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "accepted_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "denied_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": {
+ "type": "byDefault",
+ "name": "columns_id_seq",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "cache": 1,
+ "cycle": false
+ },
+ "name": "id",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "table_id",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "column_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "label",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ui_type",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "options",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "position",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "hidden",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "help_text",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": {
+ "type": "always",
+ "name": "edit_log_id_seq",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "9223372036854775807",
+ "cache": 1,
+ "cycle": false
+ },
+ "name": "id",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_email",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "schema_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "table_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "action",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pk",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "before",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "after",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": {
+ "type": "byDefault",
+ "name": "tables_id_seq",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "2147483647",
+ "cache": 1,
+ "cycle": false
+ },
+ "name": "id",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "schema_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "table_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "display_name",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "picture_url",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "editable",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "has_done",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "default_sort",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "archived_at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "opening_balance_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'spendable'",
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "include_in_total",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "color",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'personal'",
+ "generated": null,
+ "identity": null,
+ "name": "scope",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "owner",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "iban",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "external_uid",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'manual'",
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bank_balance_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bank_balance_type",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bank_balance_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'enablebanking'",
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aspsp_name",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "aspsp_country",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "psu_type",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'authorized'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "valid_until",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'[]'",
+ "generated": null,
+ "identity": null,
+ "name": "accounts",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "last_synced_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "last_error",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "amount_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "account_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "coverage",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "premium_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'monthly'",
+ "generated": null,
+ "identity": null,
+ "name": "cadence",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "investment_account_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "100000",
+ "generated": null,
+ "identity": null,
+ "name": "reserve_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "numeric(5,2)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'5.00'",
+ "generated": null,
+ "identity": null,
+ "name": "annual_return_percent",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'excess'",
+ "generated": null,
+ "identity": null,
+ "name": "contribution_mode",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "include_recurring",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "fixed_monthly_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "end_date",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "amount_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cadence",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "starts_on",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ends_on",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "account_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "account_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "amount_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "external_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'manual'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "booking_status",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "counterparty",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "raw",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value_date",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "numeric(12,3)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reading",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "numeric(12,4)",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'0'",
+ "generated": null,
+ "identity": null,
+ "name": "rate_per_unit",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "monthly_advance_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "billing_start",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "user_id",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "estimated_cents",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "3",
+ "generated": null,
+ "identity": null,
+ "name": "priority",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_id",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "key",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "market_hash_name",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "icon_url",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_type",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "first_seen_at",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "last_seen_at",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": {
+ "type": "always",
+ "name": "price_observations_id_seq",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "9223372036854775807",
+ "cache": 1,
+ "cycle": false
+ },
+ "name": "id",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_id",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "observed_at",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "price_cents",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "volume",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "imported_at",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_streams"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "currency",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_streams"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "cs",
+ "table": "price_streams"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "enabled",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'rent'",
+ "generated": null,
+ "identity": null,
+ "name": "offer",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_price",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "max_price",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_area",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_bedrooms",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "cities",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "property_types",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source_id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "external_id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "offer",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "property_type",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "street",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "postal_code",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "city",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "city_slug",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "neighbourhood",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "price_eur",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "area_m2",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rooms",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bedrooms",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bathrooms",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "construction_year",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "energy_label",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "interior",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "deposit_eur",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "available_from",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "contract_type",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "agent",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image_url",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "features",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lat",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "double precision",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lng",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "offered_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "first_seen_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'slow'",
+ "generated": null,
+ "identity": null,
+ "name": "first_seen_lane",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "last_seen_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "detail_fetched_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "removed_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "alerted_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "address_key",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "duplicate_of",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "total_price_eur",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "listing_id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "price_history"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "observed_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "price_history"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "price_eur",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "price_history"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "search_url",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lane",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "first_synced_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "last_synced_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "last_found",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "searches"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": {
+ "type": "always",
+ "name": "worker_runs_id_seq",
+ "increment": "1",
+ "startWith": "1",
+ "minValue": "1",
+ "maxValue": "9223372036854775807",
+ "cache": 1,
+ "cycle": false
+ },
+ "name": "id",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "lane",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "http_status",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "found",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "duration_ms",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "message",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'appointment'",
+ "generated": null,
+ "identity": null,
+ "name": "type",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "numeric(5,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "weight_kg",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "numeric(5,1)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "waist_cm",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "numeric(4,1)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "body_fat_pct",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'medication'",
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dose",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "frequency",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "start_date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "stop_date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kcal",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "numeric(5,1)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "protein_g",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "bedtime",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "wake_time",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "numeric(4,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": {
+ "as": "round((extract(epoch from (wake_time - bedtime)) / 3600)::numeric, 2)",
+ "type": "stored"
+ },
+ "identity": null,
+ "name": "hours",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "vaccine",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "target",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "dose_no",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "batch_lot",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "provider",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "country",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "gen_random_uuid()",
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "date",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "uuid",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "session_id",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "exercise",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sets",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reps",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "numeric(6,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "load_kg",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "numeric(3,1)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rpe",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "path",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "format",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "bigint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "size_bytes",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "sha256",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "md5",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "file_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locator",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "page",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "highlight",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "color",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "file_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "locator",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "page",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "real",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "percent",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "started_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finished_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "reading_status",
+ "typeSchema": "books",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'want_to_read'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "smallint",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "rating",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "last_read_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "file_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "started_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "ended_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "real",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "start_percent",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "real",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "end_percent",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "start_page",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "end_page",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "pages_read",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'reader'",
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "shelf_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "added_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "subtitle",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "authors",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "isbn10",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "isbn13",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "publisher",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "year",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "language",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "page_count",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "tags",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cover_url",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "cover_path",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openlibrary_work_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "openlibrary_edition_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "google_books_id",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "annas_md5",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "jsonb",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "source_refs",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "metadata_status",
+ "typeSchema": "books",
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'pending'",
+ "generated": null,
+ "identity": null,
+ "name": "metadata_status",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata_source",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metadata_fetched_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "task_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "goal_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "kind",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "from_status",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "to_status",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "note",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "numeric(14,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "value",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "description",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "color",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "archived_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'active'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "area_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "target_date",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metric",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metric_unit",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "numeric(14,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metric_target",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "numeric(14,2)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "metric_current",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "flagged",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "achieved_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "title",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'todo'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "smallint",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "priority",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "flagged",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "due_date",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "time",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "due_time",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "reminder_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "recurrence",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "area_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "goal_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "parent_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "tags",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "source",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "external_id",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "start_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "time_zone",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "started_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "completed_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "key",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "brand",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unit",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "family_key",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "favorite",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "manual",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "merged_into_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "notes",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "item_count",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "store_count",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 1,
+ "default": "'{}'",
+ "generated": null,
+ "identity": null,
+ "name": "store_ids",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_unit_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "min_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "promo_count",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image_url",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "''",
+ "generated": null,
+ "identity": null,
+ "name": "search_text",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "store_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "started_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "finished_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "'running'",
+ "generated": null,
+ "identity": null,
+ "name": "status",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "requests",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "fetched",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "inserted",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "price_changes",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "error",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "item_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "date",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "observed_on",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "promo_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "promo_label",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "store_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "store_product_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "brand",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "size_text",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unit",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "numeric(12,4)",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unit_amount",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unit_source",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "promo_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "promo_label",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "unit_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "promo_unit_price_cents",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "category_path",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "gtin",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "gtin_checked_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "image_url",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "url",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "true",
+ "generated": null,
+ "identity": null,
+ "name": "available",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "first_seen_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "last_seen_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "group_id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "match_key",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "match_method",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "real",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "match_confidence",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "boolean",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "false",
+ "generated": null,
+ "identity": null,
+ "name": "match_locked",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "type": "serial",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "id",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "slug",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "name",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "website",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "text",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "color",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "integer",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "0",
+ "generated": null,
+ "identity": null,
+ "name": "sort_order",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": false,
+ "dimensions": 0,
+ "default": null,
+ "generated": null,
+ "identity": null,
+ "name": "archived_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "created_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "type": "timestamp with time zone",
+ "typeSchema": null,
+ "notNull": true,
+ "dimensions": 0,
+ "default": "now()",
+ "generated": null,
+ "identity": null,
+ "name": "updated_at",
+ "entityType": "columns",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "account_userId_idx",
+ "entityType": "indexes",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "issuer",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "account_issuer_account_id_unique",
+ "entityType": "indexes",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "session_userId_idx",
+ "entityType": "indexes",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "identifier",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "verification_identifier_idx",
+ "entityType": "indexes",
+ "schema": "auth",
+ "table": "verification"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "pokemon_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_encounters_pokemon_id_game_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "location_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_encounters_location_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_evolutions_game_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_game_entries_game_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "catch_em_all_entries_user_id_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "catch_em_all_games_user_id_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tracker_items_game_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tracker_progress_user_id_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "osu_entries_user_id_kind_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "pokemon_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_catches_user_id_game_id_pokemon_id_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "game_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_dex_numbers_game_id_index",
+ "entityType": "indexes",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "pokemon_seen_user_id_index",
+ "entityType": "indexes",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "table_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "columns_table_id_index",
+ "entityType": "indexes",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "schema_name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "table_name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "edit_log_table_at_index",
+ "entityType": "indexes",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "accounts_user_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "bank_sessions_user_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "forecasts_user_id_date_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "insurances_user_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "recurring_user_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "transactions_user_id_date_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "account_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "transactions_account_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "utility_readings_user_id_kind_date_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ {
+ "value": "user_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "wishlist_user_id_index",
+ "entityType": "indexes",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "key",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "value",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "item_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "item_dimensions_filter_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "market_hash_name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "items_hash_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "items_name_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "item_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "currency",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "observed_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "kind",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "price_observations_unique_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "item_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "currency",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "observed_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "price_observations_lookup_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "observed_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "price_observations_time_idx",
+ "entityType": "indexes",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "source_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "listings_source_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "offer",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "first_seen_at",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "removed_at IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "listings_active_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "offer",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "city_slug",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "listings_city_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "first_seen_at",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "detail_fetched_at IS NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "listings_details_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "address_key",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": "address_key IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "listings_address_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "created_at",
+ "isExpression": false,
+ "asc": false,
+ "nullsFirst": true,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "worker_runs_created_idx",
+ "entityType": "indexes",
+ "schema": "house",
+ "table": "worker_runs"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "appointments_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "body_measurements_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "start_date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "medications_start_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "stop_date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "medications_stop_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "vaccinations_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "workouts_date_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "session_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "workouts_session_idx",
+ "entityType": "indexes",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "path",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "files_path_key",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "sha256",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "files_sha256_key",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "work_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "files_work_id_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "work_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "notes_work_id_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "work_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "progress_work_id_key",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "progress_status_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "work_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "sessions_work_id_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "sessions_started_at_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "work_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "shelf_works_work_id_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "shelves_slug_key",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "shelves"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "isbn13",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"isbn13\" is not null",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "works_isbn13_key",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "lower(\"title\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "works_title_idx",
+ "entityType": "indexes",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "task_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "activity_task_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "goal_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "created_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "activity_goal_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "areas_slug_key",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "lower(\"title\")",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "goals_title_key",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "area_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tasks_area_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "goal_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tasks_goal_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "parent_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tasks_parent_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "status",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "due_date",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tasks_status_due_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "tags",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "tasks_tags_idx",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "source",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "external_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": "\"external_id\" IS NOT NULL",
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "tasks_source_external_key",
+ "entityType": "indexes",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "key",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "groups_key_key",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "family_key",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "groups_family_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "category",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "groups_category_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "store_ids",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "groups_store_ids_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "\"search_text\" gin_trgm_ops",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "groups_search_trgm_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "store_count",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "name",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "groups_list_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "store_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "started_at",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "import_runs_store_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "item_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "observed_on",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "item_prices_item_day_key",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "store_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ },
+ {
+ "value": "store_product_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "items_store_product_key",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "group_id",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "items_group_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "gtin",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "items_gtin_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "\"name\" gin_trgm_ops",
+ "isExpression": true,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": false,
+ "where": null,
+ "with": "",
+ "method": "gin",
+ "concurrently": false,
+ "name": "items_name_trgm_idx",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ {
+ "value": "slug",
+ "isExpression": false,
+ "asc": true,
+ "nullsFirst": false,
+ "opclass": null
+ }
+ ],
+ "isUnique": true,
+ "where": null,
+ "with": "",
+ "method": "btree",
+ "concurrently": false,
+ "name": "stores_slug_key",
+ "entityType": "indexes",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "account_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "auth",
+ "table": "account"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "session_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "auth",
+ "table": "session"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "task_id"
+ ],
+ "schemaTo": "site",
+ "tableTo": "tasks",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "task_topics_task_id_tasks_id_fkey",
+ "entityType": "fks",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "topic_id"
+ ],
+ "schemaTo": "site",
+ "tableTo": "topics",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "task_topics_topic_id_topics_id_fkey",
+ "entityType": "fks",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "catch_em_all_settings_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "catch_em_all_settings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_encounters_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_encounters_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "location_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_locations",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_encounters_location_id_pokemon_locations_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_encounters"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "from_pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_evolutions_from_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "to_pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_evolutions_to_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_evolutions_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_game_entries_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_game_entries_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_game_entry_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_game_entries",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "catch_em_all_entries_HeABXvGNiB6D_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "catch_em_all_entries_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "catch_em_all_games_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "catch_em_all_games_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_items_game_id_tracker_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_progress_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "item_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_items",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_progress_item_id_tracker_items_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "osu_entries_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_catches_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_catches_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_catches_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_dex_numbers_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_dex_numbers_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_game_research_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_game_research"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_journeys_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_journeys_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_learnsets_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_milestones_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_milestones_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_research_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "pokemon_research"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_seen_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_seen_game_id_pokemon_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "pokemon",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "pokemon_seen_pokemon_id_pokemon_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_challenge_progress_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "challenge_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_challenges",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_challenge_progress_HtzyFtOyUAhk_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_challenges_game_id_tracker_games_id_fkey",
+ "entityType": "fks",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_ranks_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_games",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_ranks_game_id_tracker_games_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_weapon_ranks_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "item_id"
+ ],
+ "schemaTo": "ref",
+ "tableTo": "tracker_items",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tracker_weapon_ranks_item_id_tracker_items_id_fkey",
+ "entityType": "fks",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "sighting_id"
+ ],
+ "schemaTo": "animaldex",
+ "tableTo": "sightings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "sighting_photos_sighting_id_sightings_id_fkey",
+ "entityType": "fks",
+ "schema": "animaldex",
+ "table": "sighting_photos"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "animal_id"
+ ],
+ "schemaTo": "animaldex",
+ "tableTo": "animals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "sightings_animal_id_animals_id_fkey",
+ "entityType": "fks",
+ "schema": "animaldex",
+ "table": "sightings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "table_id"
+ ],
+ "schemaTo": "meta",
+ "tableTo": "tables",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "columns_table_id_tables_id_fkey",
+ "entityType": "fks",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "accounts_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "bank_sessions_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "forecasts_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "account_id"
+ ],
+ "schemaTo": "money",
+ "tableTo": "accounts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "forecasts_account_id_accounts_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "forecasts"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "insurances_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "projection_settings_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "investment_account_id"
+ ],
+ "schemaTo": "money",
+ "tableTo": "accounts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "projection_settings_investment_account_id_accounts_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "recurring_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "account_id"
+ ],
+ "schemaTo": "money",
+ "tableTo": "accounts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "recurring_account_id_accounts_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "transactions_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "account_id"
+ ],
+ "schemaTo": "money",
+ "tableTo": "accounts",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "NO ACTION",
+ "name": "transactions_account_id_accounts_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "utility_readings_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "utility_settings_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "schemaTo": "auth",
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "wishlist_user_id_user_id_fkey",
+ "entityType": "fks",
+ "schema": "money",
+ "table": "wishlist"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "item_id"
+ ],
+ "schemaTo": "cs",
+ "tableTo": "items",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "item_dimensions_item_id_items_id_fkey",
+ "entityType": "fks",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "item_id"
+ ],
+ "schemaTo": "cs",
+ "tableTo": "items",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "price_observations_item_id_items_id_fkey",
+ "entityType": "fks",
+ "schema": "cs",
+ "table": "price_observations"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "duplicate_of"
+ ],
+ "schemaTo": "house",
+ "tableTo": "listings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "listings_duplicate_of_listings_id_fkey",
+ "entityType": "fks",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "listing_id"
+ ],
+ "schemaTo": "house",
+ "tableTo": "listings",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "price_history_listing_id_listings_id_fkey",
+ "entityType": "fks",
+ "schema": "house",
+ "table": "price_history"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "work_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "works",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "files_work_id_works_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "files"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "work_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "works",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "notes_work_id_works_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "file_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "files",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "notes_file_id_files_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "notes"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "work_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "works",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "progress_work_id_works_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "file_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "files",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "progress_file_id_files_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "work_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "works",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "sessions_work_id_works_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "file_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "files",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "sessions_file_id_files_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "shelf_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "shelves",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "shelf_works_shelf_id_shelves_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "work_id"
+ ],
+ "schemaTo": "books",
+ "tableTo": "works",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "shelf_works_work_id_works_id_fkey",
+ "entityType": "fks",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "task_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "tasks",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "activity_task_id_tasks_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "goal_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "activity_goal_id_goals_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "area_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "areas",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "goals_area_id_areas_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "area_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "areas",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "tasks_area_id_areas_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "goal_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "goals",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "tasks_goal_id_goals_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "parent_id"
+ ],
+ "schemaTo": "tasks",
+ "tableTo": "tasks",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "tasks_parent_id_tasks_id_fkey",
+ "entityType": "fks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "merged_into_id"
+ ],
+ "schemaTo": "groceries",
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "groups_merged_into_id_groups_id_fkey",
+ "entityType": "fks",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "store_id"
+ ],
+ "schemaTo": "groceries",
+ "tableTo": "stores",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "import_runs_store_id_stores_id_fkey",
+ "entityType": "fks",
+ "schema": "groceries",
+ "table": "import_runs"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "item_id"
+ ],
+ "schemaTo": "groceries",
+ "tableTo": "items",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "item_prices_item_id_items_id_fkey",
+ "entityType": "fks",
+ "schema": "groceries",
+ "table": "item_prices"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "store_id"
+ ],
+ "schemaTo": "groceries",
+ "tableTo": "stores",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "CASCADE",
+ "name": "items_store_id_stores_id_fkey",
+ "entityType": "fks",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "group_id"
+ ],
+ "schemaTo": "groceries",
+ "tableTo": "groups",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "NO ACTION",
+ "onDelete": "SET NULL",
+ "name": "items_group_id_groups_id_fkey",
+ "entityType": "fks",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "columns": [
+ "item_id",
+ "key"
+ ],
+ "nameExplicit": true,
+ "name": "item_dimensions_pkey",
+ "entityType": "pks",
+ "schema": "cs",
+ "table": "item_dimensions"
+ },
+ {
+ "columns": [
+ "source",
+ "currency",
+ "kind"
+ ],
+ "nameExplicit": true,
+ "name": "price_streams_pkey",
+ "entityType": "pks",
+ "schema": "cs",
+ "table": "price_streams"
+ },
+ {
+ "columns": [
+ "listing_id",
+ "observed_at"
+ ],
+ "nameExplicit": true,
+ "name": "price_history_pkey",
+ "entityType": "pks",
+ "schema": "house",
+ "table": "price_history"
+ },
+ {
+ "columns": [
+ "shelf_id",
+ "work_id"
+ ],
+ "nameExplicit": false,
+ "name": "shelf_works_pkey",
+ "entityType": "pks",
+ "schema": "books",
+ "table": "shelf_works"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "account_pkey",
+ "schema": "auth",
+ "table": "account",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "session_pkey",
+ "schema": "auth",
+ "table": "session",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "user_pkey",
+ "schema": "auth",
+ "table": "user",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "verification_pkey",
+ "schema": "auth",
+ "table": "verification",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "blog_articles_pkey",
+ "schema": "site",
+ "table": "blog_articles",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tasks_pkey",
+ "schema": "site",
+ "table": "tasks",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "task_topics_pkey",
+ "schema": "site",
+ "table": "task_topics",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "topics_pkey",
+ "schema": "site",
+ "table": "topics",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "catch_em_all_settings_pkey",
+ "schema": "games",
+ "table": "catch_em_all_settings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_games_pkey",
+ "schema": "ref",
+ "table": "pokemon_games",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_pkey",
+ "schema": "ref",
+ "table": "pokemon",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_encounters_pkey",
+ "schema": "ref",
+ "table": "pokemon_encounters",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_evolutions_pkey",
+ "schema": "ref",
+ "table": "pokemon_evolutions",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_game_entries_pkey",
+ "schema": "ref",
+ "table": "pokemon_game_entries",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_locations_pkey",
+ "schema": "ref",
+ "table": "pokemon_locations",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "catch_em_all_entries_pkey",
+ "schema": "games",
+ "table": "catch_em_all_entries",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "catch_em_all_games_pkey",
+ "schema": "games",
+ "table": "catch_em_all_games",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_games_pkey",
+ "schema": "ref",
+ "table": "tracker_games",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_items_pkey",
+ "schema": "ref",
+ "table": "tracker_items",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_progress_pkey",
+ "schema": "games",
+ "table": "tracker_progress",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "osu_entries_pkey",
+ "schema": "games",
+ "table": "osu_entries",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_catches_pkey",
+ "schema": "games",
+ "table": "pokemon_catches",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_dex_numbers_pkey",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "game_id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_game_research_pkey",
+ "schema": "ref",
+ "table": "pokemon_game_research",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_journeys_pkey",
+ "schema": "games",
+ "table": "pokemon_journeys",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_learnsets_pkey",
+ "schema": "ref",
+ "table": "pokemon_learnsets",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_milestones_pkey",
+ "schema": "games",
+ "table": "pokemon_milestones",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_moves_pkey",
+ "schema": "ref",
+ "table": "pokemon_moves",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "pokemon_id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_research_pkey",
+ "schema": "ref",
+ "table": "pokemon_research",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "pokemon_seen_pkey",
+ "schema": "games",
+ "table": "pokemon_seen",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_challenge_progress_pkey",
+ "schema": "games",
+ "table": "tracker_challenge_progress",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_challenges_pkey",
+ "schema": "ref",
+ "table": "tracker_challenges",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_ranks_pkey",
+ "schema": "games",
+ "table": "tracker_ranks",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tracker_weapon_ranks_pkey",
+ "schema": "games",
+ "table": "tracker_weapon_ranks",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "animals_pkey",
+ "schema": "animaldex",
+ "table": "animals",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "sighting_photos_pkey",
+ "schema": "animaldex",
+ "table": "sighting_photos",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "sightings_pkey",
+ "schema": "animaldex",
+ "table": "sightings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "columns_pkey",
+ "schema": "meta",
+ "table": "columns",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "edit_log_pkey",
+ "schema": "meta",
+ "table": "edit_log",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tables_pkey",
+ "schema": "meta",
+ "table": "tables",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "accounts_pkey",
+ "schema": "money",
+ "table": "accounts",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "bank_sessions_pkey",
+ "schema": "money",
+ "table": "bank_sessions",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "forecasts_pkey",
+ "schema": "money",
+ "table": "forecasts",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "insurances_pkey",
+ "schema": "money",
+ "table": "insurances",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "projection_settings_pkey",
+ "schema": "money",
+ "table": "projection_settings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "recurring_pkey",
+ "schema": "money",
+ "table": "recurring",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "transactions_pkey",
+ "schema": "money",
+ "table": "transactions",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "utility_readings_pkey",
+ "schema": "money",
+ "table": "utility_readings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "utility_settings_pkey",
+ "schema": "money",
+ "table": "utility_settings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "wishlist_pkey",
+ "schema": "money",
+ "table": "wishlist",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "items_pkey",
+ "schema": "cs",
+ "table": "items",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "price_observations_pkey",
+ "schema": "cs",
+ "table": "price_observations",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "alert_rules_pkey",
+ "schema": "house",
+ "table": "alert_rules",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "listings_pkey",
+ "schema": "house",
+ "table": "listings",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "search_url"
+ ],
+ "nameExplicit": false,
+ "name": "searches_pkey",
+ "schema": "house",
+ "table": "searches",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "worker_runs_pkey",
+ "schema": "house",
+ "table": "worker_runs",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "appointments_pkey",
+ "schema": "health",
+ "table": "appointments",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "body_measurements_pkey",
+ "schema": "health",
+ "table": "body_measurements",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "medications_pkey",
+ "schema": "health",
+ "table": "medications",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "nutrition_daily_pkey",
+ "schema": "health",
+ "table": "nutrition_daily",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "sleep_pkey",
+ "schema": "health",
+ "table": "sleep",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "vaccinations_pkey",
+ "schema": "health",
+ "table": "vaccinations",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "workouts_pkey",
+ "schema": "health",
+ "table": "workouts",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "files_pkey",
+ "schema": "books",
+ "table": "files",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "notes_pkey",
+ "schema": "books",
+ "table": "notes",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "progress_pkey",
+ "schema": "books",
+ "table": "progress",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "sessions_pkey",
+ "schema": "books",
+ "table": "sessions",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "shelves_pkey",
+ "schema": "books",
+ "table": "shelves",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "works_pkey",
+ "schema": "books",
+ "table": "works",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "activity_pkey",
+ "schema": "tasks",
+ "table": "activity",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "areas_pkey",
+ "schema": "tasks",
+ "table": "areas",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "goals_pkey",
+ "schema": "tasks",
+ "table": "goals",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "tasks_pkey",
+ "schema": "tasks",
+ "table": "tasks",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "groups_pkey",
+ "schema": "groceries",
+ "table": "groups",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "import_runs_pkey",
+ "schema": "groceries",
+ "table": "import_runs",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "item_prices_pkey",
+ "schema": "groceries",
+ "table": "item_prices",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "items_pkey",
+ "schema": "groceries",
+ "table": "items",
+ "entityType": "pks"
+ },
+ {
+ "columns": [
+ "id"
+ ],
+ "nameExplicit": false,
+ "name": "stores_pkey",
+ "schema": "groceries",
+ "table": "stores",
+ "entityType": "pks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false,
+ "name": "blog_articles_slug_unique",
+ "entityType": "uniques",
+ "schema": "site",
+ "table": "blog_articles"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "task_id",
+ "topic_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "task_topics_task_id_topic_id_unique",
+ "entityType": "uniques",
+ "schema": "site",
+ "table": "task_topics"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "from_pokemon_id",
+ "to_pokemon_id",
+ "game_id",
+ "method"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_evolutions_from_pokemon_id_to_pokemon_id_game_id_method_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "pokemon_evolutions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id",
+ "game_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_game_entries_pokemon_id_game_id_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "pokemon_game_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_game_entry_id",
+ "user_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "catch_em_all_entries_pokemon_game_entry_id_user_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "catch_em_all_entries"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "catch_em_all_games_user_id_game_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "catch_em_all_games"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id",
+ "key"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_items_game_id_key_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "tracker_items"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "item_id",
+ "milestone"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_progress_user_id_item_id_milestone_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "tracker_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id",
+ "party_slot"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_catches_user_id_game_id_party_slot_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id",
+ "game_id",
+ "dex"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_dex_numbers_pokemon_id_game_id_dex_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "pokemon_dex_numbers"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_journeys_user_id_game_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "pokemon_id",
+ "version_group"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_learnsets_pokemon_id_version_group_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "pokemon_learnsets"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id",
+ "key"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_milestones_user_id_game_id_key_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "pokemon_milestones"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id",
+ "pokemon_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_seen_user_id_game_id_pokemon_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "pokemon_seen"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "challenge_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_challenge_progress_user_id_challenge_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "game_id",
+ "key"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_challenges_game_id_key_unique",
+ "entityType": "uniques",
+ "schema": "ref",
+ "table": "tracker_challenges"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "game_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_ranks_user_id_game_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "item_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_weapon_ranks_user_id_item_id_unique",
+ "entityType": "uniques",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "table_id",
+ "column_name"
+ ],
+ "nullsNotDistinct": false,
+ "name": "columns_table_id_column_name_key",
+ "entityType": "uniques",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "schema_name",
+ "table_name"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tables_schema_name_table_name_key",
+ "entityType": "uniques",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "name"
+ ],
+ "nullsNotDistinct": false,
+ "name": "accounts_user_id_name_unique",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "external_uid"
+ ],
+ "nullsNotDistinct": false,
+ "name": "accounts_external_uid_key",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "session_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "bank_sessions_session_id_key",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "projection_settings_user_id_unique",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "account_id",
+ "external_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "transactions_account_external_id_key",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id",
+ "kind"
+ ],
+ "nullsNotDistinct": false,
+ "name": "utility_settings_user_id_kind_unique",
+ "entityType": "uniques",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "token"
+ ],
+ "nullsNotDistinct": false,
+ "name": "session_token_key",
+ "schema": "auth",
+ "table": "session",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false,
+ "name": "user_email_key",
+ "schema": "auth",
+ "table": "user",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "catch_em_all_settings_user_id_key",
+ "schema": "games",
+ "table": "catch_em_all_settings",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "source_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_games_source_id_key",
+ "schema": "ref",
+ "table": "pokemon_games",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_games_slug_key",
+ "schema": "ref",
+ "table": "pokemon_games",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "number"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_number_key",
+ "schema": "ref",
+ "table": "pokemon",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "source_id"
+ ],
+ "nullsNotDistinct": false,
+ "name": "pokemon_locations_source_id_key",
+ "schema": "ref",
+ "table": "pokemon_locations",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": false,
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tracker_games_slug_key",
+ "schema": "ref",
+ "table": "tracker_games",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false,
+ "name": "tables_slug_key",
+ "schema": "meta",
+ "table": "tables",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "date"
+ ],
+ "nullsNotDistinct": false,
+ "name": "nutrition_daily_date_key",
+ "schema": "health",
+ "table": "nutrition_daily",
+ "entityType": "uniques"
+ },
+ {
+ "nameExplicit": true,
+ "columns": [
+ "date"
+ ],
+ "nullsNotDistinct": false,
+ "name": "sleep_date_key",
+ "schema": "health",
+ "table": "sleep",
+ "entityType": "uniques"
+ },
+ {
+ "value": "\"kind\" IN ('score','goal','training')",
+ "name": "osu_entries_kind_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "osu_entries"
+ },
+ {
+ "value": "\"level\" between 1 and 100",
+ "name": "pokemon_catches_level_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "value": "\"party_slot\" between 1 and 6",
+ "name": "pokemon_catches_party_slot_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "value": "cardinality(\"moves\") <= 4",
+ "name": "pokemon_catches_moves_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "value": "\"stage\" IN ('story','postgame','collection')",
+ "name": "pokemon_catches_stage_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "pokemon_catches"
+ },
+ {
+ "value": "\"stage\" IN ('story','postgame','collection')",
+ "name": "pokemon_journeys_stage_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "pokemon_journeys"
+ },
+ {
+ "value": "\"current\" >= 0",
+ "name": "tracker_challenge_progress_current_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "tracker_challenge_progress"
+ },
+ {
+ "value": "\"level\" between 1 and 10000",
+ "name": "tracker_ranks_level_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "value": "\"prestige\" between 0 and 1000",
+ "name": "tracker_ranks_prestige_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "tracker_ranks"
+ },
+ {
+ "value": "\"level\" between 1 and 10000",
+ "name": "tracker_weapon_ranks_level_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "value": "\"prestige\" between 0 and 1000",
+ "name": "tracker_weapon_ranks_prestige_check",
+ "entityType": "checks",
+ "schema": "games",
+ "table": "tracker_weapon_ranks"
+ },
+ {
+ "value": "ui_type IN ('text','longtext','url','image','number','cents','date','datetime','bool','select','multiselect','fk','json')",
+ "name": "columns_ui_type_check",
+ "entityType": "checks",
+ "schema": "meta",
+ "table": "columns"
+ },
+ {
+ "value": "action IN ('insert','update','delete','import','add_column')",
+ "name": "edit_log_action_check",
+ "entityType": "checks",
+ "schema": "meta",
+ "table": "edit_log"
+ },
+ {
+ "value": "slug ~ '^[a-z0-9][a-z0-9-]{0,62}$'",
+ "name": "tables_slug_check",
+ "entityType": "checks",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "value": "kind IN ('list','core','ref')",
+ "name": "tables_kind_check",
+ "entityType": "checks",
+ "schema": "meta",
+ "table": "tables"
+ },
+ {
+ "value": "kind IN ('spendable','investment')",
+ "name": "accounts_kind_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "value": "scope IN ('personal','joint')",
+ "name": "accounts_scope_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "value": "provider IN ('manual','enablebanking')",
+ "name": "accounts_provider_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "accounts"
+ },
+ {
+ "value": "status IN ('authorized','expired','revoked','error')",
+ "name": "bank_sessions_status_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "bank_sessions"
+ },
+ {
+ "value": "cadence IN ('weekly','monthly','yearly')",
+ "name": "insurances_cadence_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "insurances"
+ },
+ {
+ "value": "contribution_mode IN ('excess','fixed')",
+ "name": "projection_settings_contribution_mode_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "projection_settings"
+ },
+ {
+ "value": "cadence IN ('weekly','monthly','yearly')",
+ "name": "recurring_cadence_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "recurring"
+ },
+ {
+ "value": "source IN ('manual','csv','enablebanking')",
+ "name": "transactions_source_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "transactions"
+ },
+ {
+ "value": "kind IN ('electricity','gas','water')",
+ "name": "utility_readings_kind_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "utility_readings"
+ },
+ {
+ "value": "kind IN ('electricity','gas','water')",
+ "name": "utility_settings_kind_check",
+ "entityType": "checks",
+ "schema": "money",
+ "table": "utility_settings"
+ },
+ {
+ "value": "offer IN ('rent', 'buy')",
+ "name": "alert_rules_offer_check",
+ "entityType": "checks",
+ "schema": "house",
+ "table": "alert_rules"
+ },
+ {
+ "value": "offer IN ('rent', 'buy')",
+ "name": "listings_offer_check",
+ "entityType": "checks",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "value": "price_eur IS NULL OR price_eur >= 0",
+ "name": "listings_price_eur_check",
+ "entityType": "checks",
+ "schema": "house",
+ "table": "listings"
+ },
+ {
+ "value": "\"type\" IN ('appointment','checkup','condition','test','procedure','other')",
+ "name": "appointments_type_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "appointments_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "appointments"
+ },
+ {
+ "value": "\"weight_kg\" IS NOT NULL OR \"waist_cm\" IS NOT NULL OR \"body_fat_pct\" IS NOT NULL",
+ "name": "body_measurements_any_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "value": "\"weight_kg\" IS NULL OR \"weight_kg\" BETWEEN 20 AND 400",
+ "name": "body_measurements_weight_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "value": "\"waist_cm\" IS NULL OR \"waist_cm\" BETWEEN 30 AND 250",
+ "name": "body_measurements_waist_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "value": "\"body_fat_pct\" IS NULL OR \"body_fat_pct\" BETWEEN 1 AND 75",
+ "name": "body_measurements_fat_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "body_measurements_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "body_measurements"
+ },
+ {
+ "value": "length(btrim(\"name\")) > 0",
+ "name": "medications_name_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "value": "\"kind\" IN ('medication','supplement')",
+ "name": "medications_kind_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "value": "\"stop_date\" IS NULL OR \"start_date\" IS NULL OR \"stop_date\" >= \"start_date\"",
+ "name": "medications_dates_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "medications"
+ },
+ {
+ "value": "\"kcal\" IS NULL OR \"kcal\" BETWEEN 0 AND 20000",
+ "name": "nutrition_daily_kcal_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "value": "\"protein_g\" IS NULL OR \"protein_g\" BETWEEN 0 AND 1000",
+ "name": "nutrition_daily_protein_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "nutrition_daily_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "nutrition_daily"
+ },
+ {
+ "value": "\"wake_time\" > \"bedtime\"",
+ "name": "sleep_order_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "value": "\"wake_time\" - \"bedtime\" <= interval '24 hours'",
+ "name": "sleep_length_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "sleep_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "sleep"
+ },
+ {
+ "value": "length(btrim(\"vaccine\")) > 0",
+ "name": "vaccinations_vaccine_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "value": "\"dose_no\" IS NULL OR \"dose_no\" BETWEEN 1 AND 20",
+ "name": "vaccinations_dose_no_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "value": "\"country\" IS NULL OR \"country\" ~ '^[A-Z]{2}$'",
+ "name": "vaccinations_country_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "vaccinations_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "vaccinations"
+ },
+ {
+ "value": "length(btrim(\"exercise\")) > 0",
+ "name": "workouts_exercise_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"sets\" IS NULL OR \"sets\" BETWEEN 1 AND 100",
+ "name": "workouts_sets_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"reps\" IS NULL OR \"reps\" BETWEEN 0 AND 1000",
+ "name": "workouts_reps_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"load_kg\" IS NULL OR \"load_kg\" BETWEEN 0 AND 1000",
+ "name": "workouts_load_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"rpe\" IS NULL OR \"rpe\" BETWEEN 1 AND 10",
+ "name": "workouts_rpe_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"date\" >= DATE '1900-01-01'",
+ "name": "workouts_date_check",
+ "entityType": "checks",
+ "schema": "health",
+ "table": "workouts"
+ },
+ {
+ "value": "\"percent\" between 0 and 100",
+ "name": "progress_percent_check",
+ "entityType": "checks",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "value": "\"rating\" is null or \"rating\" between 1 and 5",
+ "name": "progress_rating_check",
+ "entityType": "checks",
+ "schema": "books",
+ "table": "progress"
+ },
+ {
+ "value": "(\"start_percent\" is null or \"start_percent\" between 0 and 100) and (\"end_percent\" is null or \"end_percent\" between 0 and 100)",
+ "name": "sessions_percent_check",
+ "entityType": "checks",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "value": "\"ended_at\" is null or \"ended_at\" >= \"started_at\"",
+ "name": "sessions_end_check",
+ "entityType": "checks",
+ "schema": "books",
+ "table": "sessions"
+ },
+ {
+ "value": "\"year\" is null or \"year\" between 0 and 2100",
+ "name": "works_year_check",
+ "entityType": "checks",
+ "schema": "books",
+ "table": "works"
+ },
+ {
+ "value": "\"task_id\" IS NOT NULL OR \"goal_id\" IS NOT NULL",
+ "name": "activity_target_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "value": "\"kind\" IN ('created','status','edit','note','progress')",
+ "name": "activity_kind_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "activity"
+ },
+ {
+ "value": "\"slug\" ~ '^[a-z0-9][a-z0-9-]{0,62}$'",
+ "name": "areas_slug_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "value": "length(btrim(\"name\")) > 0",
+ "name": "areas_name_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "areas"
+ },
+ {
+ "value": "length(btrim(\"title\")) > 0",
+ "name": "goals_title_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "value": "\"status\" IN ('active','achieved','dropped')",
+ "name": "goals_status_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "goals"
+ },
+ {
+ "value": "length(btrim(\"title\")) > 0",
+ "name": "tasks_title_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "value": "\"status\" IN ('todo','in_progress','done','dropped')",
+ "name": "tasks_status_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "value": "\"priority\" BETWEEN 0 AND 3",
+ "name": "tasks_priority_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "value": "\"parent_id\" IS NULL OR \"parent_id\" <> \"id\"",
+ "name": "tasks_parent_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "value": "\"due_time\" IS NULL OR \"due_date\" IS NOT NULL",
+ "name": "tasks_time_check",
+ "entityType": "checks",
+ "schema": "tasks",
+ "table": "tasks"
+ },
+ {
+ "value": "length(btrim(\"name\")) > 0",
+ "name": "groups_name_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "value": "\"unit\" IS NULL OR \"unit\" IN ('piece','kg','l')",
+ "name": "groups_unit_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "value": "\"merged_into_id\" IS NULL OR \"merged_into_id\" <> \"id\"",
+ "name": "groups_not_self_merged",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "groups"
+ },
+ {
+ "value": "\"unit\" IS NULL OR \"unit\" IN ('piece','kg','l')",
+ "name": "items_unit_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "value": "\"price_cents\" IS NULL OR \"price_cents\" >= 0",
+ "name": "items_price_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "items"
+ },
+ {
+ "value": "\"slug\" ~ '^[a-z0-9][a-z0-9-]{0,62}$'",
+ "name": "stores_slug_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "stores"
+ },
+ {
+ "value": "length(btrim(\"name\")) > 0",
+ "name": "stores_name_check",
+ "entityType": "checks",
+ "schema": "groceries",
+ "table": "stores"
+ }
+ ],
+ "renames": []
+}
\ No newline at end of file
diff --git a/scripts/house-db.sh b/scripts/house-db.sh
new file mode 100755
index 0000000..8daecb9
--- /dev/null
+++ b/scripts/house-db.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+# Run a house-tracker script against prod with the limited house_cli role
+# (house.listings + house.price_history only), without the app's credentials.
+# scripts/house-db.sh list --city gouda
+# scripts/house-db.sh add --street "Raam 12" --city Gouda --price 1475
+# Credentials: ~/.config/house-cli.env (DB_URL=..., mode 600, readable by stan only).
+set -euo pipefail
+cd "$(dirname "$0")/.."
+env_file="${HOUSE_CLI_ENV:-$HOME/.config/house-cli.env}"
+[ -r "$env_file" ] || { echo "missing $env_file" >&2; exit 1; }
+unset DATABASE_URL DB_URL
+exec bun --env-file="$env_file" scripts/house-listing.ts "$@"
diff --git a/scripts/house-scrape.ts b/scripts/house-scrape.ts
new file mode 100644
index 0000000..a0e11ca
--- /dev/null
+++ b/scripts/house-scrape.ts
@@ -0,0 +1,282 @@
+// Nightly house scraper, run on stan-vm by a systemd user timer (deploy/systemd/house-scrape.*).
+// Fetches the sources that allow it, writes house.listings directly and pushes an ntfy alert
+// for new listings that match an alert rule. See docs/house-tracker.md.
+//
+// bun --env-file=$HOME/.config/house-scrape.env scripts/house-scrape.ts [--dry-run] [--source kamernet]
+//
+// Politeness: one request at a time, 6-10 s apart, an honest User-Agent, robots.txt-allowed
+// paths only. A 403/429/challenge stops that source for the night; nothing is retried or
+// worked around. Funda, Pararius, huurwoningen.nl and Huurstunt challenge this server's
+// (datacenter) IP, so they are not scraped from here.
+import postgres from 'postgres';
+import { alertMessage, matchesRule, type AlertRule } from '../src/lib/house-tracker/alerts';
+import { citySlug } from '../src/lib/house-tracker/address';
+import { dedupe, ingestListings } from '../src/lib/house-tracker/ingest';
+import { kamernetSearchUrl, parseKamernetSearch } from '../src/lib/house-tracker/kamernet';
+import { isChallenge } from '../src/lib/house-tracker/pararius';
+import type { ScrapedListing } from '../src/lib/house-tracker/scraped';
+import {
+ parseVestedaSearch,
+ VESTEDA_SEARCH_URL,
+ vestedaSearchBody
+} from '../src/lib/house-tracker/vesteda';
+
+const args = process.argv.slice(2);
+const dryRun = args.includes('--dry-run');
+const only = args.includes('--source') ? args[args.indexOf('--source') + 1] : null;
+
+const USER_AGENT =
+ 'stanrunge.dev-house-tracker/1.0 (personal use, one run per night; stan@stanrunge.dev)';
+const KAMERNET_CITIES = (
+ process.env.HOUSE_KAMERNET_CITIES ??
+ 'gouda,waddinxveen,reeuwijk,bodegraven,boskoop,schoonhoven,oudewater,moordrecht,zevenhuizen,nieuwerkerk-aan-den-ijssel'
+)
+ .split(',')
+ .map((c) => c.trim())
+ .filter(Boolean);
+const KAMERNET_MAX_PAGES = 5;
+// Gouda centre; Vesteda's own search uses km radius around a point.
+const VESTEDA = {
+ lat: 52.0115,
+ lng: 4.7105,
+ radiusKm: Number(process.env.HOUSE_VESTEDA_RADIUS_KM ?? 20),
+ place: 'Gouda'
+};
+const MAX_ALERTS = 5;
+
+const dbUrl = process.env.DB_URL ?? process.env.DATABASE_URL;
+if (!dbUrl && !dryRun) throw new Error('DB_URL is not set');
+const sql = dbUrl ? postgres(dbUrl, { max: 1, connect_timeout: 10, onnotice: () => {} }) : null;
+
+class Blocked extends Error {
+ constructor(
+ public status: number,
+ public url: string
+ ) {
+ super(`blocked (${status}) on ${url}`);
+ }
+}
+
+let lastRequest = 0;
+async function politeFetch(url: string, init: RequestInit = {}): Promise {
+ const wait = lastRequest + 6000 + Math.random() * 4000 - Date.now();
+ if (wait > 0) await Bun.sleep(wait);
+ lastRequest = Date.now();
+ const response = await fetch(url, {
+ ...init,
+ redirect: 'follow',
+ signal: AbortSignal.timeout(30_000),
+ headers: {
+ 'user-agent': USER_AGENT,
+ 'accept-language': 'nl-NL,nl;q=0.9,en;q=0.5',
+ ...(init.headers ?? {})
+ }
+ });
+ return response;
+}
+
+async function logRun(
+ source: string,
+ url: string,
+ status: string,
+ extra: { httpStatus?: number; found?: number; durationMs?: number; message?: string } = {}
+) {
+ console.log(
+ `${source} ${status}${extra.httpStatus ? ` ${extra.httpStatus}` : ''} ${extra.found ?? ''} ${url}${extra.message ? ` (${extra.message})` : ''}`
+ );
+ if (!sql || dryRun) return;
+ await sql`INSERT INTO house.worker_runs (source, lane, url, status, http_status, found, duration_ms, message)
+ VALUES (${source}, 'nightly', ${url}, ${status}, ${extra.httpStatus ?? null}, ${extra.found ?? null},
+ ${extra.durationMs ?? null}, ${extra.message?.slice(0, 500) ?? null})`;
+}
+
+type SourceResult = { listings: ScrapedListing[]; completed: boolean };
+
+async function scrapeKamernet(): Promise {
+ const listings: ScrapedListing[] = [];
+ let completed = true;
+ for (const city of KAMERNET_CITIES) {
+ for (let page = 1; page <= KAMERNET_MAX_PAGES; page++) {
+ const url = kamernetSearchUrl(city, page);
+ const started = Date.now();
+ const response = await politeFetch(url, { headers: { accept: 'text/html' } });
+ const html = await response.text();
+ if (isChallenge(html, response.status)) {
+ await logRun('kamernet', url, 'challenged', { httpStatus: response.status });
+ throw new Blocked(response.status, url);
+ }
+ if (response.status === 404) {
+ // Kamernet has no page for some small places; that is not an error.
+ await logRun('kamernet', url, 'ok', {
+ httpStatus: 404,
+ found: 0,
+ message: 'no such city page'
+ });
+ break;
+ }
+ if (!response.ok) {
+ await logRun('kamernet', url, 'http-error', { httpStatus: response.status });
+ completed = false;
+ break;
+ }
+ try {
+ const result = parseKamernetSearch(html);
+ // Kamernet widens the search to nearby places; keep each city's own listings once.
+ listings.push(...result.listings);
+ await logRun('kamernet', url, 'ok', {
+ httpStatus: 200,
+ found: result.listings.length,
+ durationMs: Date.now() - started
+ });
+ const pages = result.total && result.perPage ? Math.ceil(result.total / result.perPage) : 1;
+ if (page >= pages) break;
+ } catch (error) {
+ await logRun('kamernet', url, 'parse-error', { httpStatus: 200, message: String(error) });
+ completed = false;
+ break;
+ }
+ }
+ }
+ return { listings, completed };
+}
+
+async function scrapeVesteda(): Promise {
+ const started = Date.now();
+ const response = await politeFetch(VESTEDA_SEARCH_URL, {
+ method: 'POST',
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
+ body: JSON.stringify(vestedaSearchBody(VESTEDA))
+ });
+ const text = await response.text();
+ if (isChallenge(text, response.status)) {
+ await logRun('vesteda', VESTEDA_SEARCH_URL, 'challenged', { httpStatus: response.status });
+ throw new Blocked(response.status, VESTEDA_SEARCH_URL);
+ }
+ if (!response.ok) {
+ await logRun('vesteda', VESTEDA_SEARCH_URL, 'http-error', { httpStatus: response.status });
+ return { listings: [], completed: false };
+ }
+ try {
+ const listings = parseVestedaSearch(JSON.parse(text));
+ await logRun('vesteda', VESTEDA_SEARCH_URL, 'ok', {
+ httpStatus: 200,
+ found: listings.length,
+ durationMs: Date.now() - started
+ });
+ return { listings, completed: true };
+ } catch (error) {
+ await logRun('vesteda', VESTEDA_SEARCH_URL, 'parse-error', {
+ httpStatus: 200,
+ message: String(error)
+ });
+ return { listings: [], completed: false };
+ }
+}
+
+async function ntfy(title: string, body: string, click: string) {
+ const target = process.env.HOUSE_NTFY_URL;
+ if (!target) return false;
+ const url = new URL(target);
+ const response = await fetch(url.origin, {
+ method: 'POST',
+ headers: {
+ 'content-type': 'application/json',
+ ...(process.env.HOUSE_NTFY_TOKEN
+ ? { authorization: `Bearer ${process.env.HOUSE_NTFY_TOKEN}` }
+ : {})
+ },
+ body: JSON.stringify({
+ topic: url.pathname.replace(/^\/+|\/+$/g, ''),
+ title,
+ message: body,
+ click,
+ tags: ['house'],
+ priority: 3
+ }),
+ signal: AbortSignal.timeout(10_000)
+ }).catch(() => null);
+ return Boolean(response?.ok);
+}
+
+const sources: Record Promise> = {
+ kamernet: scrapeKamernet,
+ vesteda: scrapeVesteda
+};
+const fresh: { id: number; source: string; listing: ScrapedListing }[] = [];
+let failures = 0;
+try {
+ for (const [name, scrape] of Object.entries(sources)) {
+ if (only && only !== name) continue;
+ const runStartedAt = new Date();
+ let result: SourceResult;
+ try {
+ result = await scrape();
+ } catch (error) {
+ failures++;
+ console.error(
+ `${name}: ${error instanceof Error ? error.message : error}; skipped until tomorrow`
+ );
+ continue;
+ }
+ if (dryRun || !sql) {
+ for (const l of result.listings)
+ console.log(
+ ` ${l.sourceId} €${l.priceEur ?? '?'} ${l.areaM2 ?? '?'}m² ${l.title} (${l.city}) ${l.url}`
+ );
+ continue;
+ }
+ // An empty result from a "complete" run is more likely a broken page than an empty market.
+ const completed = result.completed && result.listings.length > 0;
+ const ingest = await ingestListings(sql, name, result.listings, { runStartedAt, completed });
+ console.log(
+ `${name}: ${result.listings.length} seen, ${ingest.inserted.length} new${ingest.seeded ? ' (first run: seeded, no alerts)' : ''}, ${ingest.updated} updated, ${ingest.removed} gone`
+ );
+ if (!ingest.seeded) for (const row of ingest.inserted) fresh.push({ ...row, source: name });
+ }
+
+ if (sql && !dryRun) {
+ const { keyed, copies } = await dedupe(sql);
+ console.log(`dedupe: ${keyed} new address keys, ${copies} listings are copies of another`);
+
+ const rules =
+ (await sql`SELECT id, name, enabled, offer, min_price AS "minPrice", max_price AS "maxPrice",
+ min_area AS "minArea", min_bedrooms AS "minBedrooms", cities, property_types AS "propertyTypes"
+ FROM house.alert_rules WHERE enabled`) as unknown as AlertRule[];
+ const copyIds = new Set(
+ fresh.length
+ ? (
+ await sql<
+ { id: number }[]
+ >`SELECT id FROM house.listings WHERE duplicate_of IS NOT NULL AND id IN ${sql(fresh.map((f) => f.id))}`
+ ).map((r) => r.id)
+ : []
+ );
+ const matches = fresh.flatMap((f) => {
+ if (copyIds.has(f.id)) return [];
+ const listing = { ...f.listing, citySlug: citySlug(f.listing.city), source: f.source };
+ const rule = rules.find((r) => matchesRule(listing, r));
+ return rule ? [{ ...f, message: alertMessage(listing, rule) }] : [];
+ });
+ let sent = 0;
+ for (const match of matches.slice(0, MAX_ALERTS)) {
+ if (await ntfy(match.message.title, match.message.body, match.message.url)) {
+ sent++;
+ await sql`UPDATE house.listings SET alerted_at = now() WHERE id = ${match.id}`;
+ }
+ }
+ if (matches.length > MAX_ALERTS)
+ await ntfy(
+ `🏠 ${matches.length - MAX_ALERTS} more new listings`,
+ 'See the house tracker.',
+ 'https://stanrunge.dev/trackers/houses?status='
+ );
+ console.log(
+ `alerts: ${matches.length} new matches, ${sent} sent${process.env.HOUSE_NTFY_URL ? '' : ' (HOUSE_NTFY_URL not set)'}`
+ );
+ }
+} finally {
+ await sql?.end();
+}
+
+// Non-zero so systemd shows the unit as failed when a source broke or blocked us.
+if (failures > 0) process.exitCode = 1;
diff --git a/src/lib/house-tracker/address.test.ts b/src/lib/house-tracker/address.test.ts
new file mode 100644
index 0000000..7371bfe
--- /dev/null
+++ b/src/lib/house-tracker/address.test.ts
@@ -0,0 +1,28 @@
+import { describe, expect, it } from 'vitest';
+import { addressKey, citySlug, normalizeHouseNumber, splitAddress } from './address';
+
+describe('address keys', () => {
+ it('matches abbreviations and number formats across sources', () => {
+ const manual = splitAddress('Burg. van Dijkesingel 214-B');
+ expect(manual).toEqual({ street: 'Burg. van Dijkesingel', houseNumber: '214-B' });
+ const a = addressKey(manual.street, manual.houseNumber, 'Gouda');
+ const b = addressKey('Burgemeester Van Dijkesingel', '214 B', 'GOUDA');
+ expect(a).toBe('burgemeester van dijkesingel|214b|gouda');
+ expect(b).toBe(a);
+ });
+ it('keeps unit numbers apart', () => {
+ expect(normalizeHouseNumber('1-206')).toBe('1-206');
+ expect(normalizeHouseNumber('16')).toBe('16');
+ expect(normalizeHouseNumber('16a')).toBe('16a');
+ expect(splitAddress('Noothoven van Goorstraat 1-206').houseNumber).toBe('1-206');
+ });
+ it('has no key without a house number', () => {
+ expect(addressKey('Raam', null, 'Gouda')).toBeNull();
+ expect(splitAddress('Raam')).toEqual({ street: 'Raam', houseNumber: null });
+ });
+ it('slugs city names', () => {
+ expect(citySlug('Nieuwerkerk a/d IJssel')).toBe('nieuwerkerk-aan-den-ijssel');
+ expect(citySlug('Capelle Aan Den Ijssel')).toBe('capelle-aan-den-ijssel');
+ expect(citySlug('Alphen aan den Rijn')).toBe('alphen-aan-den-rijn');
+ });
+});
diff --git a/src/lib/house-tracker/address.ts b/src/lib/house-tracker/address.ts
new file mode 100644
index 0000000..a9ac5c7
--- /dev/null
+++ b/src/lib/house-tracker/address.ts
@@ -0,0 +1,104 @@
+// Address normalisation for de-duplicating the same home across sources. Pure, no imports
+// from #lib or $app: the nightly scraper runs this with plain bun.
+
+const abbreviations: [RegExp, string][] = [
+ [/\bburg\b\.?/g, 'burgemeester'],
+ [/\bmr\b\.?/g, 'meester'],
+ [/\bdr\b\.?/g, 'dokter'],
+ [/\bprof\b\.?/g, 'professor'],
+ [/\bst\b\.?/g, 'sint'],
+ [/\bpr\b\.?/g, 'prins'],
+ [/\bkon\b\.?/g, 'koningin'],
+ [/\bv\b\.?/g, 'van']
+];
+
+function plain(value: string): string {
+ return value
+ .normalize('NFD')
+ .replace(/[\u0300-\u036f]/g, '')
+ .toLowerCase();
+}
+
+/** "Nieuwerkerk a/d IJssel" -> "nieuwerkerk-aan-den-ijssel", "Capelle Aan Den Ijssel" -> "capelle-aan-den-ijssel". */
+export function citySlug(city: string | null | undefined): string | null {
+ if (!city) return null;
+ const slug = plain(city)
+ .replace(/\ba\s*\/\s*d\b/g, 'aan den')
+ .replace(/\ba\s*d\b(?=\s)/g, 'aan den')
+ .replace(/[^a-z0-9]+/g, '-')
+ .replace(/^-+|-+$/g, '');
+ return slug || null;
+}
+
+export function normalizeStreet(street: string): string {
+ let s = plain(street).replace(/[.,'’]/g, ' ');
+ for (const [pattern, full] of abbreviations) s = s.replace(pattern, full);
+ return s
+ .replace(/[^a-z0-9 ]+/g, ' ')
+ .replace(/\s+/g, ' ')
+ .trim();
+}
+
+/** "214-B", "214 b", "214B" -> "214b"; "1-206" stays "1-206" (number + unit). */
+export function normalizeHouseNumber(value: string): string | null {
+ const s = plain(value).replace(/\s+/g, '');
+ const match = /^(\d+)(?:[-/]?([a-z]{1,3}|\d{1,4}))?/.exec(s);
+ if (!match) return null;
+ const [, number, addition] = match;
+ if (!addition) return number;
+ return /^\d+$/.test(addition) ? `${number}-${addition}` : `${number}${addition}`;
+}
+
+/** Split "Burg. van Dijkesingel 214-B" into street and number. */
+export function splitAddress(address: string): { street: string; houseNumber: string | null } {
+ const match = /^(.*?\D)\s+(\d+(?:\s*[-/]?\s*[a-z0-9]{1,4})?)\s*$/i.exec(address.trim());
+ if (!match) return { street: address.trim(), houseNumber: null };
+ return { street: match[1].trim(), houseNumber: match[2].replace(/\s+/g, '') };
+}
+
+/**
+ * Key for "is this the same home": street + house number (+ addition) + city. Null when the
+ * number is unknown, because "Raam, Gouda" alone can be dozens of different homes.
+ */
+export function addressKey(
+ street: string | null | undefined,
+ houseNumber: string | null | undefined,
+ city: string | null | undefined
+): string | null {
+ if (!street || !houseNumber || !city) return null;
+ const number = normalizeHouseNumber(houseNumber);
+ const slug = citySlug(city);
+ if (!number || !slug) return null;
+ return `${normalizeStreet(street)}|${number}|${slug}`;
+}
+
+/**
+ * Marks copies: for every address key, the manual entry (else the oldest row) is the
+ * original; all other rows with that key point at it. Rows whose key went away are reset.
+ * Two statements, run one after the other.
+ */
+export const DEDUPE_SQL = [
+ `WITH canon AS (
+ SELECT DISTINCT ON (address_key) address_key, id
+ FROM house.listings
+ WHERE address_key IS NOT NULL
+ ORDER BY address_key, (source = 'manual') DESC, id
+ )
+ UPDATE house.listings l
+ SET duplicate_of = CASE WHEN l.id = canon.id THEN NULL ELSE canon.id END
+ FROM canon
+ WHERE l.address_key = canon.address_key
+ AND l.duplicate_of IS DISTINCT FROM (CASE WHEN l.id = canon.id THEN NULL ELSE canon.id END)`,
+ `UPDATE house.listings SET duplicate_of = NULL
+ WHERE duplicate_of IS NOT NULL AND address_key IS NULL`
+] as const;
+
+/** Address key from free text such as a street column ("Raam 12") or a manual title. */
+export function addressKeyFromText(
+ text: string | null | undefined,
+ city: string | null | undefined
+) {
+ if (!text) return null;
+ const { street, houseNumber } = splitAddress(text.replace(/,.*$/, ''));
+ return addressKey(street, houseNumber, city);
+}
diff --git a/src/lib/house-tracker/fixtures/kamernet-search-gouda.html b/src/lib/house-tracker/fixtures/kamernet-search-gouda.html
new file mode 100644
index 0000000..22dc4bd
--- /dev/null
+++ b/src/lib/house-tracker/fixtures/kamernet-search-gouda.html
@@ -0,0 +1 @@
+Huurwoningen Gouda | Kamernet
diff --git a/src/lib/house-tracker/fixtures/vesteda-search-gouda.json b/src/lib/house-tracker/fixtures/vesteda-search-gouda.json
new file mode 100644
index 0000000..e3867ba
--- /dev/null
+++ b/src/lib/house-tracker/fixtures/vesteda-search-gouda.json
@@ -0,0 +1,190 @@
+{
+ "results": {
+ "objects": [
+ {
+ "id": 180703,
+ "code": null,
+ "vgoNumber": "VGO0039253",
+ "street": "Burgemeester Van Dijkesingel",
+ "houseNumber": "133",
+ "houseNumberAddition": null,
+ "postalCode": "2809RB",
+ "city": "Gouda",
+ "complex": "Westergouwe",
+ "complexId": 1084,
+ "size": 122,
+ "priceUnformatted": 1840.0,
+ "price": "\u20ac 1840,-",
+ "numberOfBedRooms": 3,
+ "latitude": 52.00515,
+ "longitude": 4.676554,
+ "imageSmall": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/bb/bb163ed427176aa2a2ee67e787ceac15/o/01.jpg?rmode=crop&width=285&height=138&hmac=aa7d7722e40664b531084c35436529bdf4e6fb42097d5e9b88703e3bf26da2e3",
+ "imageBig": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/bb/bb163ed427176aa2a2ee67e787ceac15/o/01.jpg?rmode=crop&width=570&height=276&hmac=1f9433d024630b48be34533abecbde50374f09a29c6ab100d3ddea791c54cedc",
+ "subImages": null,
+ "district": null,
+ "location": "Gouda, Zuid-west",
+ "status": 1,
+ "alt": "01.jpg",
+ "url": "/nl/westergouwe/burgemeester-van-dijkesingel-133-gouda-180703",
+ "upcomingeventdate": null,
+ "suitedForHomeSharers": false,
+ "ageFrom": 0,
+ "onlySixtyFivePlus": false,
+ "prioritizeKeyProfessions": false,
+ "onlyMiddleRent": false,
+ "entitytypeid": 1,
+ "entitysubtypeid": 1,
+ "entitysubtypelabel": "Eengezinswoning",
+ "entityguid": "8bb3e01c0f666d83179a4155704249bd",
+ "complexguid": "679caab4522de3f9df0d9a2938dd45c2",
+ "complexTopComplex": false,
+ "complexPeriodicallyAvailable": false,
+ "complexPriceMin": 0,
+ "complexPriceMax": 0,
+ "complexManuallyAdded": false,
+ "priorityArrangement": null,
+ "isExclusive": null,
+ "features": null
+ },
+ {
+ "id": 50503,
+ "code": null,
+ "vgoNumber": "VGO0041768",
+ "street": "Jozefhof",
+ "houseNumber": "123",
+ "houseNumberAddition": null,
+ "postalCode": "2805PX",
+ "city": "Gouda",
+ "complex": "Goudshof",
+ "complexId": 1111,
+ "size": 81,
+ "priceUnformatted": 1350.0,
+ "price": "\u20ac 1350,-",
+ "numberOfBedRooms": 2,
+ "latitude": 52.01952,
+ "longitude": 4.714698,
+ "imageSmall": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/b5/b54175d6c8e11196a40647b89b6c7062/o/jozefhof-305-02.jpg?rmode=crop&width=285&height=138&hmac=44381f8dbcb1165d08d16065c8dcac889c632d299bb4c70eeb9b1bf9d9f54a1c",
+ "imageBig": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/b5/b54175d6c8e11196a40647b89b6c7062/o/jozefhof-305-02.jpg?rmode=crop&width=570&height=276&hmac=78bef49237059606f93a676383c124d75518575265ce291188811b9a7e53f255",
+ "subImages": null,
+ "district": null,
+ "location": "Gouda, Zuid-west",
+ "status": 3,
+ "alt": "jozefhof-305-02.jpg",
+ "url": "/nl/goudshof/jozefhof-123-gouda-50503",
+ "upcomingeventdate": null,
+ "suitedForHomeSharers": false,
+ "ageFrom": 0,
+ "onlySixtyFivePlus": false,
+ "prioritizeKeyProfessions": false,
+ "onlyMiddleRent": false,
+ "entitytypeid": 1,
+ "entitysubtypeid": 2,
+ "entitysubtypelabel": "Appartement",
+ "entityguid": "cb39d0883a5e9bed32c505ab3b2ebdc9",
+ "complexguid": "cd43201a0ce690e02f6c0ed5c4e62329",
+ "complexTopComplex": false,
+ "complexPeriodicallyAvailable": false,
+ "complexPriceMin": 0,
+ "complexPriceMax": 0,
+ "complexManuallyAdded": false,
+ "priorityArrangement": null,
+ "isExclusive": null,
+ "features": null
+ },
+ {
+ "id": 186080,
+ "code": null,
+ "vgoNumber": "VGO0043608",
+ "street": "Grote Beer",
+ "houseNumber": "13",
+ "houseNumberAddition": "A-17",
+ "postalCode": "3067TR",
+ "city": "Rotterdam",
+ "complex": "Grote Beer",
+ "complexId": 3992,
+ "size": 89,
+ "priceUnformatted": 1715.0,
+ "price": "\u20ac 1715,-",
+ "numberOfBedRooms": 2,
+ "latitude": 51.949135,
+ "longitude": 4.555593,
+ "imageSmall": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/e7/e7daf84af0fee447527762f43aaa9d5e/o/01.jpg?rmode=crop&width=285&height=138&hmac=9e1210e6efa1673aac5e9d8afc05d70bee952644f6f12f31137d7baccda7c7e0",
+ "imageBig": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/e7/e7daf84af0fee447527762f43aaa9d5e/o/01.jpg?rmode=crop&width=570&height=276&hmac=b184dd1372d52b98dfd14f0517e11acaf737d3ed388a84a1763ee3e7d929d3a9",
+ "subImages": null,
+ "district": null,
+ "location": "Rotterdam, Zuid-west",
+ "status": 3,
+ "alt": "01.jpg",
+ "url": "/nl/huurwoningen-rotterdam/grote-beer/grote-beer-13a-17-rotterdam-186080",
+ "upcomingeventdate": null,
+ "suitedForHomeSharers": false,
+ "ageFrom": 0,
+ "onlySixtyFivePlus": false,
+ "prioritizeKeyProfessions": false,
+ "onlyMiddleRent": false,
+ "entitytypeid": 1,
+ "entitysubtypeid": 2,
+ "entitysubtypelabel": "Appartement",
+ "entityguid": "d804fa9630e12d81157f02c2cfe3cb6d",
+ "complexguid": "eee8500ca94a555eb096ad955a5211f2",
+ "complexTopComplex": false,
+ "complexPeriodicallyAvailable": false,
+ "complexPriceMin": 0,
+ "complexPriceMax": 0,
+ "complexManuallyAdded": false,
+ "priorityArrangement": null,
+ "isExclusive": null,
+ "features": null
+ },
+ {
+ "id": 38568,
+ "code": null,
+ "vgoNumber": "VGO0022549",
+ "street": "Wijde Wormer",
+ "houseNumber": "258",
+ "houseNumberAddition": null,
+ "postalCode": "2905TZ",
+ "city": "Capelle Aan Den Ijssel",
+ "complex": "Wijde Wormer",
+ "complexId": 789,
+ "size": 89,
+ "priceUnformatted": 1335.0,
+ "price": "\u20ac 1335,-",
+ "numberOfBedRooms": 1,
+ "latitude": 51.94391,
+ "longitude": 4.603301,
+ "imageSmall": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/b6/b6ad9be5e74e91259171847e77998922/o/15766-wijde-wormer-capelle-ad-ijssel-1-.jpg?rmode=crop&width=285&height=138&hmac=103847240a4e830421ae06bdb3736d71e840581af9687d14280055bd5f52abcd",
+ "imageBig": "https://vst-web-prod-cdn-remote-media-endpoint-a4eufkf7anbjhkab.z03.azurefd.net/verhuuroffice.nl/media/b6/b6ad9be5e74e91259171847e77998922/o/15766-wijde-wormer-capelle-ad-ijssel-1-.jpg?rmode=crop&width=570&height=276&hmac=277f47bc35200032906b35cb42d979768c35d3c861903cc559dab2e4bc91519f",
+ "subImages": null,
+ "district": null,
+ "location": "Capelle Aan Den Ijssel, Zuid-west",
+ "status": 2,
+ "alt": "15766-wijde-wormer-capelle-ad-ijssel-1-.jpg",
+ "url": "/nl/huurwoningen-capelle-aan-den-ijssel/wijde-wormer/wijde-wormer-258-capelle-aan-den-ijssel-38568",
+ "upcomingeventdate": null,
+ "suitedForHomeSharers": false,
+ "ageFrom": 0,
+ "onlySixtyFivePlus": false,
+ "prioritizeKeyProfessions": false,
+ "onlyMiddleRent": false,
+ "entitytypeid": 1,
+ "entitysubtypeid": 2,
+ "entitysubtypelabel": "Appartement",
+ "entityguid": "04266b6d1e2dec652c42344ea580f1e3",
+ "complexguid": "42b912d58daf28809cac51ae25db6dd4",
+ "complexTopComplex": false,
+ "complexPeriodicallyAvailable": false,
+ "complexPriceMin": 0,
+ "complexPriceMax": 0,
+ "complexManuallyAdded": false,
+ "priorityArrangement": false,
+ "isExclusive": null,
+ "features": null
+ }
+ ],
+ "objectsCount": 4,
+ "complexes": [],
+ "newComplexes": []
+ },
+ "count": 4
+}
\ No newline at end of file
diff --git a/src/lib/house-tracker/ingest.ts b/src/lib/house-tracker/ingest.ts
new file mode 100644
index 0000000..a45f535
--- /dev/null
+++ b/src/lib/house-tracker/ingest.ts
@@ -0,0 +1,124 @@
+// Writes scraped listings into house.listings with plain postgres.js, for the nightly
+// scraper on stan-vm (scripts/house-scrape.ts). No #lib / $app imports.
+import type postgres from 'postgres';
+import { addressKey, addressKeyFromText, citySlug, DEDUPE_SQL } from './address';
+import type { ScrapedListing } from './scraped';
+
+type Sql = postgres.Sql;
+
+export type IngestResult = {
+ seeded: boolean;
+ inserted: { id: number; listing: ScrapedListing }[];
+ updated: number;
+ removed: number;
+};
+
+export async function ingestListings(
+ sql: Sql,
+ source: string,
+ listings: ScrapedListing[],
+ opts: { runStartedAt: Date; completed: boolean }
+): Promise {
+ // The same listing can show up on two city pages; keep the first.
+ const unique = [...new Map(listings.map((l) => [l.sourceId, l])).values()];
+ return sql.begin(async (tx) => {
+ const [any] = await tx`SELECT 1 FROM house.listings WHERE source = ${source} LIMIT 1`;
+ const seeded = !any;
+ const ids = unique.map((l) => l.sourceId);
+ const existing = ids.length
+ ? await tx<{ id: number; source_id: string; price_eur: number | null }[]>`
+ SELECT id, source_id, price_eur FROM house.listings
+ WHERE source = ${source} AND source_id IN ${tx(ids)}`
+ : [];
+ const known = new Map(existing.map((row) => [row.source_id, row]));
+ const inserted: IngestResult['inserted'] = [];
+ let updated = 0;
+
+ for (const l of unique) {
+ const columns = {
+ url: l.url,
+ title: l.title,
+ street: l.houseNumber ? `${l.street ?? ''} ${l.houseNumber}`.trim() : l.street,
+ postal_code: l.postalCode,
+ city: l.city,
+ city_slug: citySlug(l.city),
+ price_eur: l.priceEur,
+ total_price_eur: l.totalPriceEur,
+ area_m2: l.areaM2,
+ rooms: l.rooms,
+ bedrooms: l.bedrooms,
+ energy_label: l.energyLabel,
+ available_from: l.availableFrom,
+ interior: l.interior,
+ agent: l.agent,
+ image_url: l.imageUrl,
+ lat: l.lat,
+ lng: l.lng,
+ features: tx.json(l.features),
+ address_key: addressKey(l.street, l.houseNumber, l.city)
+ };
+ const previous = known.get(l.sourceId);
+ if (previous) {
+ await tx`UPDATE house.listings SET ${tx(columns)}, last_seen_at = now(), removed_at = NULL
+ WHERE id = ${previous.id}`;
+ if (l.priceEur != null && l.priceEur !== previous.price_eur)
+ await tx`INSERT INTO house.price_history (listing_id, price_eur) VALUES (${previous.id}, ${l.priceEur})`;
+ updated++;
+ continue;
+ }
+ const [row] = await tx<{ id: number }[]>`INSERT INTO house.listings ${tx({
+ ...columns,
+ source,
+ source_id: l.sourceId,
+ offer: l.offer,
+ property_type: l.propertyType,
+ first_seen_lane: seeded ? 'seed' : 'nightly',
+ // Everything the source offers is already in the search result.
+ detail_fetched_at: new Date()
+ })} ON CONFLICT (source, source_id) DO NOTHING RETURNING id`;
+ if (!row) continue;
+ if (l.priceEur != null)
+ await tx`INSERT INTO house.price_history (listing_id, price_eur) VALUES (${row.id}, ${l.priceEur})`;
+ inserted.push({ id: row.id, listing: l });
+ }
+
+ let removed = 0;
+ if (opts.completed) {
+ const gone = await tx`UPDATE house.listings SET removed_at = now()
+ WHERE source = ${source} AND removed_at IS NULL AND last_seen_at < ${opts.runStartedAt}
+ RETURNING id`;
+ removed = gone.length;
+ }
+ return { seeded, inserted, updated, removed };
+ });
+}
+
+/**
+ * Fills address_key for rows written elsewhere (manual CLI, Pararius worker) from their
+ * street or title, then marks cross-source copies. Safe to run any time.
+ */
+export async function dedupe(sql: Sql): Promise<{ keyed: number; copies: number }> {
+ const rows = await sql<
+ {
+ id: number;
+ source: string;
+ street: string | null;
+ title: string | null;
+ city: string | null;
+ }[]
+ >`SELECT id, source, street, title, city FROM house.listings
+ WHERE address_key IS NULL AND (street IS NOT NULL OR source = 'manual')`;
+ let keyed = 0;
+ for (const row of rows) {
+ const key =
+ addressKeyFromText(row.street, row.city) ??
+ (row.source === 'manual' ? addressKeyFromText(row.title, row.city) : null);
+ if (!key) continue;
+ await sql`UPDATE house.listings SET address_key = ${key} WHERE id = ${row.id}`;
+ keyed++;
+ }
+ for (const statement of DEDUPE_SQL) await sql.unsafe(statement);
+ const [{ copies }] = await sql<{ copies: number }[]>`
+ SELECT count(*)::int AS copies FROM house.listings WHERE duplicate_of IS NOT NULL`;
+ return { keyed, copies };
+}
diff --git a/src/lib/house-tracker/kamernet.ts b/src/lib/house-tracker/kamernet.ts
new file mode 100644
index 0000000..8bdb960
--- /dev/null
+++ b/src/lib/house-tracker/kamernet.ts
@@ -0,0 +1,81 @@
+// Kamernet search pages (kamernet.nl/huren/huurwoningen-). The page is server-rendered
+// Next.js; the listings sit in the __NEXT_DATA__ JSON, so no HTML scraping is needed.
+// /huren/ is allowed in Kamernet's robots.txt.
+import { int, str, type ScrapedListing, type SearchPage } from './scraped';
+import type { PropertyType } from './types';
+
+export const KAMERNET_ORIGIN = 'https://kamernet.nl';
+
+// listingType -> (URL word, our type). Seen on the site: 1 kamer, 2 appartement, 4 studio.
+const types: Record = {
+ 1: ['kamer', 'room'],
+ 2: ['appartement', 'apartment'],
+ 4: ['studio', 'studio'],
+ 8: ['anti-kraak', 'other']
+};
+const furnishing: Record = { 1: 'kaal', 2: 'gestoffeerd', 4: 'gemeubileerd' };
+
+export function kamernetSearchUrl(citySlug: string, page = 1): string {
+ const url = `${KAMERNET_ORIGIN}/huren/huurwoningen-${citySlug}`;
+ return page > 1 ? `${url}?pageNo=${page}` : url;
+}
+
+type RawListing = Record;
+
+export function parseKamernetSearch(html: string): SearchPage {
+ const match = /
- house tracker
+ houses
-
house tracker
+
houses
{data.health.total} listings collected · {data.health.alerts_week}
{data.health.alerts_week === 1 ? 'alert' : 'alerts'} this week
@@ -92,11 +92,11 @@
]}
>
{#if workerState === 'challenged'}
- worker was challenged {relativeTime(data.health.last_challenge!, now)}, backing off
+ a source blocked the scraper {relativeTime(data.health.last_challenge!, now)} (see the log)
{:else if data.health.last_ok}
- worker last synced {relativeTime(data.health.last_ok, now)}
+ scraper last ran {relativeTime(data.health.last_ok, now)}
{:else}
- worker has not synced yet
+ scraper has not run yet
{/if}
@@ -107,6 +107,7 @@
buy
+ Gouda region
all cities
{#each data.cities as city (city.slug)}
{city.name ?? city.slug} ({city.active})
@@ -114,6 +115,26 @@
+
+
+
+ all sources
+ {#each data.sources as row (row.source)}
+ {row.source} ({row.active})
+ {/each}
+
newest
@@ -176,7 +197,16 @@
{listing.title ?? 'Listing'}
- {price(listing.priceEur)}
+
+ {price(listing.priceEur)}
+ {#if listing.totalPriceEur && listing.totalPriceEur !== listing.priceEur}
+ ({euro.format(listing.totalPriceEur)} total)
+ {:else if listing.totalPriceEur}
+ incl. utilities
+ {/if}
+
+
+
+ {listing.notes ? 'notes' : 'add notes'}
+
+
+
(event.currentTarget as HTMLSelectElement).form?.requestSubmit()}
>
- —
+ new
{#each data.statuses as status (status)}{status} {/each}
save
@@ -241,7 +302,7 @@
{:else}
- No listings yet. Start the home worker (see docs/house-tracker.md).
+ No listings match. Clear some filters, or wait for tonight's scrape.
{/each}
@@ -251,6 +312,32 @@
{/if}
+ add a listing by hand
+
+
+
+
+
+
+
+
+ new
+ {#each data.statuses as status (status)}{status} {/each}
+
+
+ add
+
+
+ Same address or link as an existing listing updates it. Scraped copies of the same address are
+ linked to it automatically.
+
+ {#if form?.message}{form.message}
{/if}
+
market ({data.filters.offer})