Provides direct query access to the GOAT PostgreSQL database for debugging and state inspection.
Install
mkdir -p .claude/skills/db-plan4better && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/17324" && unzip -o skill.zip -d .claude/skills/db-plan4better && rm skill.zipInstalls to .claude/skills/db-plan4better
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Use when inspecting, debugging, or understanding the GOAT PostgreSQL database — querying projects, layers, users, orgs, teams, roles, scenarios, jobs, or checking data state during local dev.Key capabilities
- →Connect to the GOAT PostgreSQL database via Docker
- →Execute one-off SQL queries against the database
- →Inspect database schemas and table relationships
- →Query specific tables like `customer.project`, `customer.layer`, `customer.job`, `customer.scenario_feature`
- →Retrieve common data patterns like projects with layer counts or job statuses
- →Understand how layer metadata and data are stored
How it works
The skill connects to the GOAT PostgreSQL database through its running Docker container, allowing execution of read-only SQL queries and inspection of schemas and table relationships to understand data state.
Inputs & outputs
When to use db
- →Debug database state
- →Run ad-hoc SQL queries
- →Inspect schema relationships
About this skill
Database Query
Query the GOAT PostgreSQL database to inspect data, debug issues, and understand state.
Connection
There is no host psql; go through the running Postgres container. The container name changes
across setups (goat-db, goat-db18, …), so discover it rather than hardcoding:
source /home/p4b/goat/.env
DBC=$(docker ps --format '{{.Names}}' | grep -E '^goat-db' | head -1)
docker exec -e PGPASSWORD=$POSTGRES_PASSWORD "$DBC" psql -h 127.0.0.1 -U $POSTGRES_USER -d $POSTGRES_DB
One-off query:
source /home/p4b/goat/.env
DBC=$(docker ps --format '{{.Names}}' | grep -E '^goat-db' | head -1)
docker exec -e PGPASSWORD=$POSTGRES_PASSWORD "$DBC" psql -h 127.0.0.1 -U $POSTGRES_USER -d $POSTGRES_DB -c "YOUR SQL HERE"
Schemas
| Schema | Purpose |
|---|---|
customer | Everything: users, orgs, teams, roles/permissions, projects, layers, scenarios, jobs, workflows |
ducklake | DuckLake catalog (managed by geoapi, don't modify directly) |
Key Tables & Relationships
The SQLModel definitions in apps/core are the source of truth — introspect when unsure:
SELECT table_name FROM information_schema.tables WHERE table_schema='customer' ORDER BY 1;
\d customer.layer
Identity & sharing (all in customer)
- user (id uuid) — Keycloak-synced. firstname, lastname, avatar
- organization (id uuid) — name, avatar; organization_domain, organization_analytics
- team (id uuid) — belongs to org. name, avatar
- role (id uuid) — permission roles; RBAC via permission, role_permission, user_role, resource, resource_grant, resource_permission
- user_team — M2M user ↔ team; invitation — pending org/team invites
- layer_organization / layer_team / layer_user — layer sharing with role
- project_organization / project_team / project_user — project sharing with role
Projects, layers & scenarios (customer)
- project (id uuid) — user_id, folder_id, active_scenario_id, layer_order[], basemap, tags[]
- layer (id uuid) — user_id, folder_id, data_store_id. Key fields: name, type, data_type, tool_type, feature_layer_type, feature_layer_geometry_type, extent (geometry), properties (jsonb), url, size, attribute_mapping (jsonb), in_catalog, tags[]
- layer_project (id int) — M2M layer ↔ project. name, properties (jsonb style config), other_properties, query (jsonb filters), charts, order, layer_project_group_id
- layer_project_group (id int) — layer groups. project_id, parent_id (self-ref nesting), order
- data_store (id uuid) — storage backends. type
- folder (id uuid) — user_id, name
- job (id uuid) — user_id. type, status, payload (jsonb)
- scenario (id uuid) — project_id, user_id, name
- scenario_feature (id uuid) — layer_project_id, feature_id (text), edit_type, geom, h3_3, h3_6. Generic typed columns: integer_attr1..25, float_attr1..25, text_attr1..25, plus bigint/jsonb/boolean/array/timestamp attrs
- scenario_scenario_feature — M2M scenario ↔ scenario_feature
- workflow (id uuid) — project_id, name, config (jsonb), is_default
- report / report_layout (id uuid) — project_id, name, config (jsonb), is_default
- project_public — public sharing config: password, config (jsonb snapshot)
- user_project — user ↔ project with initial_view_state (jsonb)
- system_setting — per-user: client_theme, preferred_language, unit
- uploaded_asset — user uploads: s3_key, file_name, mime_type, file_size, asset_type, content_hash
- cost / credit_usage — credit metering
Common Queries
-- Projects with layer counts
SELECT p.id, p.name, p.created_at, COUNT(lp.id) AS layer_count
FROM customer.project p
LEFT JOIN customer.layer_project lp ON lp.project_id = p.id
GROUP BY p.id ORDER BY p.created_at DESC;
-- Layers in a project with styles
SELECT lp.id, lp.name, lp.order, l.type, l.feature_layer_type, l.feature_layer_geometry_type
FROM customer.layer_project lp
JOIN customer.layer l ON l.id = lp.layer_id
WHERE lp.project_id = 'PROJECT_UUID'
ORDER BY lp.order;
-- Job status
SELECT id, type, status, created_at, payload->>'tool_type' AS tool
FROM customer.job ORDER BY created_at DESC LIMIT 10;
-- Scenario features for a scenario
SELECT sf.id, sf.feature_id, sf.edit_type, ST_AsText(sf.geom) AS geom
FROM customer.scenario_feature sf
JOIN customer.scenario_scenario_feature ssf ON ssf.scenario_feature_id = sf.id
WHERE ssf.scenario_id = 'SCENARIO_UUID';
Important Notes
- Layer metadata lives in PostgreSQL (
customer.layer), layer data lives in DuckLake (managed by geoapi) layer_project.properties= style/rendering config (jsonb);layer_project.query= active filters (jsonb)scenario_featureuses generic columns (integer_attr1..25 etc.) — checklayer.attribute_mappingfor which attr maps to which real column name- A public dashboard reads the
project_public.configsnapshot, not the live project — re-publish to reflect changes - Always use READ-ONLY queries. Never INSERT/UPDATE/DELETE unless explicitly asked
- Use
ST_AsText()orST_AsGeoJSON()to read geometry columns
When not to use it
- →When performing INSERT, UPDATE, or DELETE operations unless explicitly asked
- →When the database is not GOAT PostgreSQL or not running in a Docker container
- →When the user needs to interact with the DuckLake catalog directly
Limitations
- →The skill only supports connecting to the GOAT PostgreSQL database via its Docker container
- →The skill is designed for READ-ONLY queries; INSERT/UPDATE/DELETE are not allowed unless explicitly asked
- →The skill does not directly modify DuckLake catalog data
How it compares
This skill provides a containerized and controlled method for database inspection and debugging, ensuring safe read-only access and consistent connection, unlike direct host `psql` access which might be unavailable or less secure.
Compared to similar skills
db side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| db (this skill) | 0 | 18d | Review | Intermediate |
| data-sql | 0 | 3mo | No flags | Intermediate |
| data-safety-auditor | 3 | 7mo | No flags | Advanced |
| supabase-incident-runbook | 1 | 10d | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
data-sql
nholder88
>-
data-safety-auditor
ananddtyagi
Comprehensive data safety auditor for Vue 3 + Pinia + IndexedDB + PouchDB applications. Detects data loss risks, sync issues, race conditions, and browser-specific vulnerabilities with actionable remediation guidance.
supabase-incident-runbook
jeremylongshore
Execute Supabase incident response procedures with triage, mitigation, and postmortem. Use when responding to Supabase-related outages, investigating errors, or running post-incident reviews for Supabase integration failures. Trigger with phrases like "supabase incident", "supabase outage", "supabase down", "supabase on-call", "supabase emergency", "supabase broken".
supabase-advanced-troubleshooting
jeremylongshore
Execute apply Supabase advanced debugging techniques for hard-to-diagnose issues. Use when standard troubleshooting fails, investigating complex race conditions, or preparing evidence bundles for Supabase support escalation. Trigger with phrases like "supabase hard bug", "supabase mystery error", "supabase impossible to debug", "difficult supabase issue", "supabase deep debug".
plain-optimize
dropseed
Captures and analyzes performance traces to identify slow queries and N+1 problems. Use when analyzing performance or optimizing database queries.
audit
senda-labs
Run complete system health audit of DQIII8 — checks DB integrity, agent performance, pipeline connections, error log, and services. Produces a scored Markdown report.