---
title: Expose careerlog net first-N-season and best-season fields
type: task
status: completed
description: >-
  The league_format_player_careerlogs net first-N-season and best-season columns exist but no
  data-view field reads them, while every _earned counterpart is registered. Parity work, no DDL.
base_uri: user:task/league/expose-careerlog-net-first-n-season-fields.md
created_at: '2026-08-05T00:00:37.021Z'
entity_id: 1104af37-52e7-447f-8640-73270939105f
finished_at: '2026-08-05T01:55:45.217Z'
observations:
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
  - ████████████████████████████████████████████████
owner_identity_uri: █████████████████████████
priority: Low
public_read: true
relations:
  - relates [[user:task/league/surface-projected-points-added-net.md]]
  - relates [[███████████████████████████-████-██-██████-███████████]]
tags:
  - user:tag/league-xo-football.md
updated_at: '2026-08-05T01:55:45.217Z'
visibility_analyzed_at: '2026-11-05T23:49:13.235Z'
---

# Expose careerlog net first-N-season and best-season fields

## Problem

`league_format_player_careerlogs` carries the net variant of the first-N-season and best-season aggregates, and `libs-shared/data-view-fields-index.mjs` exposes only the `_earned` side of that family. The columns exist in `db/schema.postgres.sql`:

- `points_added_net_first_season`, `_second_season`, `_third_season`
- `points_added_net_first_three_seasons`, `_first_four_seasons`, `_first_five_seasons`
- `best_season_points_added_net_per_game`

Their `_earned` counterparts are all registered as data-view fields. The net ones are reachable by nothing, which is the same gap [[user:task/league/surface-projected-points-added-net.md]] closed on the projected rest-of-season side.

## Scope

Register the missing fields in `libs-shared/data-view-fields-index.mjs` and their column definitions in `libs-server/data-views-column-definitions/player-league-format-logs-column-definitions.mjs`, following the existing `create_field_from_league_format_player_careerlogs` pattern.

No DDL. No rename — the shipped `_earned` spelling stays until the cutover owned by [[███████████████████████████-████-██-██████-███████████]].

## Verify

- The SQL validity gate (`node db/adhoc/check-data-view-sql-validity.mjs`) passes from a clean worktree at HEAD.
- A golden exercising at least one new field goes red before the change and green after.
- Registering a field needs no saved-view migration, since no saved view can reference an id that did not exist.

## Plan

- [x] **Register the seven missing net careerlog fields**
  - Description: add each to `libs-shared/data-view-fields-index.mjs` with a column definition built by `create_field_from_league_format_player_careerlogs`, mirroring the `_earned` entries directly above them.
  - Purpose: the columns are populated and no consumer can reach them.
  - Verify: each field returns non-null for a player with the corresponding `_earned` value populated.

- [x] **Add a golden and run the SQL validity gate**
  - Description: one data-view fixture covering at least one new field; then `node db/adhoc/check-data-view-sql-validity.mjs` from a clean worktree at HEAD.
  - Purpose: nothing else pins the emitted SQL, and the gate reads the working tree.
  - Verify: the new golden is red before the change and green after, with `skip_query_match` unset; gate exits 0.
