> **Plain-language companion:** [v0.75.0.md](v0.75.0.md) ## v0.75.0 — API Polish, Documentation Excellence & Developer Experience **Status: Released.** Derived from [ROADMAP.md](../ROADMAP.md). > **Release Theme** > Polish the SQL API surface and documentation to meet the world-class standard > required before v1.0. This release normalises the API catalog, adds missing > SQL reference sections, introduces type-safety wrappers for cross-domain > identifiers, repairs doc corruption, and delivers the comparison matrix that > operators need when evaluating pg_trickle against alternative IVM systems. --- ### Implementation Status | Item | Title | Status | |------|-------|--------| | API-002 | `pgtrickle.metrics_summary` full SQL reference section | ✅ Done | | API-003 | SQL function parameter naming convention documented | ✅ Done | | API-004 | Generated API catalog return types converted to SQL-facing forms | ✅ Done | | API-005 | Schedule-mode comparison table added to SQL reference | ✅ Done | | CODE-003 | Typed `PgtId` / `StreamTableOid` wrappers in Rust | ✅ Done | | DOC-001 | `plans/PLAN.md` architecture-doc table repaired + fragment-corruption lint | ✅ Done | | DOC-002 | README GUC count updated to generated phrase | ✅ Done | | DOC-003 | `metrics_summary()` section added to detailed SQL reference (same as API-002) | ✅ Done | | DOC-004 | Stale-version scanner added to docs lint | ✅ Done | | ARCH-004 | `docs/COMPARISONS.md` comprehensive IVM comparison matrix | ✅ Done | --- ### Detailed Item Descriptions #### API-002 / DOC-003 — `metrics_summary()` Full SQL Reference Section **Source:** PLAN_OVERALL_ASSESSMENT_14.md §API-002, §DOC-003 **Severity:** Medium **Location:** `src/api/metrics_ext.rs`, `docs/SQL_REFERENCE.md`, `docs/SQL_API_CATALOG.md` `metrics_summary()` appears in the generated API catalog but has no detailed section in `docs/SQL_REFERENCE.md`, unlike `cache_stats()` and `history_prune_status()`. Add a full section with: - Function signature and SETOF column list - Per-column descriptions with operational notes - Grafana usage guidance (typical Grafana/Prometheus query pattern) - Cost caveats (aggregates from `pgt_refresh_summary` — O(N stream tables) per call; do not call on every scrape for large installations) - Example output row **Exit criterion:** `grep -c "metrics_summary" docs/SQL_REFERENCE.md` ≥ 2 (TOC link + section heading). --- #### API-003 — SQL Function Parameter Naming Convention **Source:** PLAN_OVERALL_ASSESSMENT_14.md §API-003 **Severity:** Medium **Location:** `src/api/create.rs`, `src/api/outbox.rs`, `src/api/spec.rs`, `docs/SQL_REFERENCE.md` Core functions use bare names (`name`, `query`), while newer APIs use `p_name`, `p_retention_hours`, or overload-specific names. This is visible in named- argument SQL calls and generated docs. Document the convention as a note in `docs/SQL_REFERENCE.md` (or a dedicated SQL API conventions section): prefer bare user-facing argument names (`name`, `query`, `schedule`); keep `p_` prefix only for internal wrappers or where migration compatibility requires it. **Exit criterion:** Convention documented in `docs/SQL_REFERENCE.md`. --- #### API-004 — Generated API Catalog: SQL-Facing Return Types **Source:** PLAN_OVERALL_ASSESSMENT_14.md §API-004 **Severity:** Medium **Location:** `scripts/gen_catalogs.py`, `docs/SQL_API_CATALOG.md` The catalog quality gate passes, but many rows show Rust return types: `Result<(), PgTrickleError>`, `pgrx::JsonB (nullable)`, `String`, `&'static str`, `bool`, etc. Convert these to SQL-facing forms in `_normalize_return_type()`: | Rust | SQL | |------|-----| | `Result<(), PgTrickleError>` | `void` | | `Result` | `text` | | `Result` | `bigint` | | `pgrx::JsonB` | `jsonb` | | `String` | `text` | | `&'static str` | `text` | | `bool` | `boolean` | | `i32` | `integer` | | `i64` | `bigint` | | `f64` | `double precision` | Keep Rust return metadata in a developer-only footnote if needed. **Exit criterion:** `grep "Result<\|pgrx::\|&'static" docs/SQL_API_CATALOG.md` returns zero matches after regeneration. --- #### API-005 — Schedule-Mode Comparison Table **Source:** PLAN_OVERALL_ASSESSMENT_14.md §API-005 **Severity:** Low **Location:** `docs/SQL_REFERENCE.md` Add a compact comparison table for Duration / Cron / CALCULATED / IMMEDIATE with use-case, example, and refresh-trigger semantics. Place it immediately after the cron expression format table and before the first example. **Exit criterion:** Table present in `docs/SQL_REFERENCE.md` schedule section. --- #### CODE-003 — Typed `PgtId` / `StreamTableOid` Wrappers **Source:** PLAN_OVERALL_ASSESSMENT_14.md §CODE-003 **Severity:** Low **Location:** `src/api/outbox.rs`, `src/catalog.rs` Casting `pgt_id: i64` into `pgt_relid: pg_sys::Oid` blurs two unrelated identifier domains. Introduce: - `PgtId(i64)` — internal sequence ID for a stream table row - `StreamTableOid(pg_sys::Oid)` — PostgreSQL relation OID visible in `pg_class` These newtype wrappers make cross-domain casts hard to write accidentally. Add `From` / `Into` impls for the underlying types and update the outbox helper functions to use them. **Exit criterion:** `grep "pgt_id as Oid\|pgt_id.*into.*Oid" src/` returns zero matches. --- #### DOC-001 — Repair `plans/PLAN.md` Architecture-Doc Table **Source:** PLAN_OVERALL_ASSESSMENT_14.md §DOC-001 **Severity:** Medium **Location:** `plans/PLAN.md` The Key Architecture Docs table contains duplicated fragments and corrupted text (`COST_MODEL` repeated, `LIMITATIONS` truncated with random chars). Fix the table by restoring the intended rows. Add a fragment-corruption lint to `scripts/check_docs_truth.py` (or a new `scripts/check_plan_index.py`) that fails if any Markdown link in `plans/PLAN.md` contains non-word characters inside the link text (indicating corruption). **Exit criterion:** `plans/PLAN.md` table renders correctly; lint passes in CI. --- #### DOC-002 — README GUC Count: Generated Phrase **Source:** PLAN_OVERALL_ASSESSMENT_14.md §DOC-002 **Severity:** Medium **Location:** `README.md:558` `README.md` says "All 115 configuration parameters" but the generated GUC catalog now reports 132. Replace the hard-coded count with a phrase that doesn't require manual updates: e.g., "All configuration parameters with types and defaults". **Exit criterion:** `grep "All [0-9]* configuration parameters" README.md` returns zero matches. --- #### DOC-004 — Stale-Version Scanner **Source:** PLAN_OVERALL_ASSESSMENT_14.md §DOC-004, §DEVEX-003 **Severity:** Low **Location:** `Dockerfile.hub`, `Dockerfile.ghcr`, `scripts/` Dockerfile comment examples still show `0.11.0-pg18` and `0.13.0-pg18.3`. Add a `scripts/check_stale_versions.sh` script that: 1. Reads the current Cargo.toml version. 2. Scans a list of files for version-like patterns that do NOT match the current version or a known placeholder (``, `@CARGO_VERSION@`, `latest`). 3. Reports stale occurrences and exits 1 if any are found. Wire it into `just lint-ci`. **Exit criterion:** Script present; `just lint-ci` runs it; Dockerfile comments updated to use `` placeholders. --- #### ARCH-004 — `docs/COMPARISONS.md` Comprehensive IVM Comparison Matrix **Source:** PLAN_OVERALL_ASSESSMENT_14.md §ARCH-004 **Severity:** Low **Location:** `docs/COMPARISONS.md` `docs/COMPARISONS.md` exists but lacks: 1. A section on **Feldera** (open-source DBSP-based streaming SQL engine) 2. A unified comparison matrix across SQL coverage, consistency model, CDC model, performance characteristics, and operational model for all five systems: pg_ivm, Materialize, Feldera, DuckDB/DuckLake, and pg_trickle Add both. The matrix should cover at least these axes: | Axis | Description | |------|-------------| | SQL coverage | SELECT features supported (joins, aggregates, recursion, etc.) | | Consistency model | How fresh are results? At what isolation level? | | CDC model | How are source changes detected? | | Performance | Throughput / latency profile | | Operational model | What do you deploy? Where does the data live? | **Exit criterion:** `docs/COMPARISONS.md` contains a Feldera section and a comprehensive cross-system matrix. --- ### Phase Order 1. DOC-001 (quick fix, unblocks docs-lint) 2. DOC-002 + DOC-004 (README + Dockerfile + scanner, low risk) 3. API-004 (gen_catalogs.py, regenerate catalog, verify CI) 4. API-002/DOC-003 (SQL reference section, no code change) 5. API-003 (convention note, no code change) 6. API-005 (SQL reference table, no code change) 7. ARCH-004 (expand COMPARISONS.md) 8. CODE-003 (Rust type wrappers — highest compile risk, do last) --- ### Exit Criteria Checklist - [x] API-002/DOC-003: `metrics_summary` section present in `docs/SQL_REFERENCE.md` - [x] API-003: Parameter naming convention documented - [x] API-004: `docs/SQL_API_CATALOG.md` contains no bare Rust types after regen - [x] API-005: Schedule-mode comparison table in SQL reference - [x] CODE-003: `PgtId` / `StreamTableOid` newtypes in `src/catalog.rs`; outbox helpers use them - [x] DOC-001: `plans/PLAN.md` table not corrupted; fragment-corruption lint passes - [x] DOC-002: README GUC count is not a hard-coded number - [x] DOC-004: Stale-version scanner in `scripts/`; Dockerfile comments use `` - [x] ARCH-004: `docs/COMPARISONS.md` has Feldera section and comprehensive matrix - [x] `just fmt && just lint` passes with zero warnings - [x] `just test-unit` passes - [x] Version bumped to 0.75.0 in `Cargo.toml`, `META.json`, `pg_trickle.control` - [x] `CHANGELOG.md` updated - [x] `ROADMAP.md` v0.75.0 status → Released - [x] `roadmap/v0.75.0.md` created