Scope the table-info counts to the territory

table-info feeds two things and was scoped for neither: the status bar's
"total rows", and the figure the load progress promises while it waits. So
an account that can see a fraction of the table was told the whole size of
it -- jbukowski's 542k rows reported as 2.8M.

It only showed on the larger territories. The seeded figure is replaced by
X-Row-Count when the headers arrive, and on a small territory the aggregate
returns fast enough that the wrong number barely appears.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-09-18 13:29:52 -04:00
parent 5cc59b5792
commit f2734ab5b2

View File

@ -1,6 +1,7 @@
const express = require('express');
const { fcTable, mapType } = require('../lib/utils');
const { sessionUser } = require('../lib/auth');
const { sessionUser, sessionTerritory } = require('../lib/auth');
const { buildTerritoryClause } = require('../lib/sql_generator');
module.exports = function(pool) {
const router = express.Router();
@ -194,7 +195,7 @@ ${colDefs},
router.get('/versions/:id/table-info', async (req, res) => {
try {
const verResult = await pool.query(`
SELECT v.id, v.name, v.status, s.schema, s.tname
SELECT v.id, v.name, v.status, s.schema, s.tname, s.id AS source_id
FROM pf.version v
JOIN pf.source s ON s.id = v.source_id
WHERE v.id = $1
@ -210,10 +211,23 @@ ${colDefs},
);
const exists = existsResult.rows[0].exists;
// Scoped like every other read. Unscoped it reported the whole
// table to an account that can see a fraction of it -- the status
// bar's row count, and the figure the load progress promises, both
// came from here: a rep with 330k rows was told the load was
// fetching 2.8M.
const terrCol = (await pool.query(
`SELECT cname FROM pf.col_meta WHERE source_id = $1 AND is_territory LIMIT 1`,
[v.source_id]
)).rows[0]?.cname || null;
const terr = buildTerritoryClause(sessionTerritory(req), terrCol);
let rows = null, byIter = [];
if (exists) {
const countResult = await pool.query(
`SELECT pf_iter, count(*)::int AS n FROM ${fc} GROUP BY pf_iter ORDER BY pf_iter`
`SELECT pf_iter, count(*)::int AS n FROM ${fc}
${terr ? `WHERE ${terr}` : ''}
GROUP BY pf_iter ORDER BY pf_iter`
);
byIter = countResult.rows;
rows = byIter.reduce((a, r) => a + r.n, 0);