CtrlK
BlogDocsLog inGet started
Tessl Logo

alonso-skills/postgres-writing-guidelines

Use when writing or reviewing PostgreSQL/PL-pgSQL, designing table schemas, writing functions and procedures, building migrations, defining domains, or architecting a Postgres application database. Also use when writing RAISE EXCEPTION patterns, BEFORE/AFTER triggers for cross-table constraints, base/subtype hierarchies, composite key designs, row-level security policies, or idempotent DDL scripts. If you are touching Postgres for an application database, use this skill. PostgreSQL-specific — examples will not run on other engines.

84

1.72x
Quality

89%

Does it follow best practices?

Impact

100%

1.72x

Average score across 2 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-1/

{
  "context": "Tests whether the agent follows PostgreSQL writing guidelines when designing an e-commerce schema: naming conventions (snake_case, prefixed objects), domain-based column types, hierarchical composite keys, base/subtype inheritance, cross-table trigger enforcement, and correct procedure/function/view naming.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "snake_case identifiers",
      "description": "All table, column, function, procedure, trigger, view, and constraint names use snake_case — no PascalCase or camelCase identifiers anywhere in the file",
      "max_score": 6
    },
    {
      "name": "Domain columns only",
      "description": "Table column definitions use named DOMAINs (e.g., email, customer_no, money_amount) rather than bare built-in types (VARCHAR, INT, BIGINT, BOOLEAN, TIMESTAMPTZ) directly in column definitions",
      "max_score": 10
    },
    {
      "name": "Domains NOT NULL",
      "description": "Domain definitions include NOT NULL (nullable columns are the exception, not the default)",
      "max_score": 6
    },
    {
      "name": "Type catalog YAML present",
      "description": "A YAML file (e.g., types.yaml or domains.yaml) is present listing the defined custom types with their base types, organized by category or as a flat list",
      "max_score": 6
    },
    {
      "name": "Procedure naming (pr_)",
      "description": "Stored procedures use the pr_ prefix and non-SQL-keyword verbs (add, modify, remove) — e.g., pr_add_order, pr_add_order_line — not create_, insert_, update_, or delete_",
      "max_score": 6
    },
    {
      "name": "Function naming (fn_)",
      "description": "Functions use the fn_ prefix — e.g., fn_find_customer — not get_, fetch_, or bare descriptive names without prefix",
      "max_score": 6
    },
    {
      "name": "View naming (vw_)",
      "description": "Views use the vw_<role>_<intent> naming convention — e.g., vw_customer_my_orders — not plain descriptive names",
      "max_score": 6
    },
    {
      "name": "Trigger function naming (tg_)",
      "description": "Trigger functions use the tg_<subject>_<action> prefix — e.g., tg_payment_method_check_customer — not plain descriptive function names",
      "max_score": 6
    },
    {
      "name": "Constraint names as predicates",
      "description": "Named constraints use the subject_relationship_object predicate form (e.g., payment_method_belongs_to_customer, customer_must_have_valid_email) rather than mechanism names like fk_payment_customer or chk_email",
      "max_score": 7
    },
    {
      "name": "Hierarchical composite PKs",
      "description": "The order line (and/or shipment) table uses a composite primary key that includes the parent's primary key columns (e.g., (customer_no, order_no, line_no)) rather than an independent BIGSERIAL/IDENTITY surrogate",
      "max_score": 10
    },
    {
      "name": "Base/subtype PK-FK pattern",
      "description": "Subtype tables (e.g., premium_customer or account subtypes) use the explicit PK-as-FK pattern: the subtype's PK references the base table's PK as a foreign key, and does NOT use Postgres INHERITS",
      "max_score": 8
    },
    {
      "name": "Cross-table constraint via trigger",
      "description": "Cross-table constraints (e.g., verifying that a payment method's customer is verified before insert) are enforced via a BEFORE trigger that calls a separate function, rather than a CHECK constraint",
      "max_score": 8
    },
    {
      "name": "Trigger thin, logic in function",
      "description": "The trigger body is a one-liner calling a tg_ function — the actual validation logic lives in the function, not inline in the trigger",
      "max_score": 7
    },
    {
      "name": "p_ / v_ parameter naming",
      "description": "Procedure and function parameters are prefixed with p_ and local PL/pgSQL variables are prefixed with v_",
      "max_score": 4
    },
    {
      "name": "Reference table seeded with ON CONFLICT",
      "description": "Any reference/lookup table (e.g., account_type, order_status) is seeded with INSERT ... ON CONFLICT DO NOTHING in the same script",
      "max_score": 4
    }
  ]
}

evals

scenario-1

criteria.json

task.md

SKILL.md

tile.json