feat(map): ingest audited department zone snapshot

This commit is contained in:
Codex
2026-07-21 12:02:11 +03:00
parent 3446f3edc2
commit 343812b90d
19 changed files with 76785 additions and 105 deletions
+45 -1
View File
@@ -2,9 +2,12 @@ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
import { createReadStream, createWriteStream } from "node:fs";
import { chmod, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
import { createServer } from "node:http";
import { dirname, join } from "node:path";
import { dirname, join, resolve } from "node:path";
import { Readable, Transform } from "node:stream";
import { pipeline } from "node:stream/promises";
import { fileURLToPath } from "node:url";
import { loadZoneSourceProfile } from "./zone-source-snapshot.mjs";
const canonicalCesiumAssetIds = ["1", "2", "96188"];
const cesiumVerificationTransportVersion = 4;
@@ -20,6 +23,15 @@ const canonicalCesiumEgressHosts = new Set([
"ecn.t3.tiles.virtualearth.net",
]);
const config = await readConfig();
const zoneSourceProfileId = String(process.env.ZONE_SOURCE_PROFILE_ID || "moscow-pmd-slow-zones").trim();
const zoneSourceRoot = resolve(String(
process.env.ZONE_SOURCE_SNAPSHOT_ROOT
|| resolve(dirname(fileURLToPath(import.meta.url)), "../zone-sources"),
).trim());
// The route contract is stable while the provider behind this profile is
// replaceable: today it is the audited MMap snapshot, later an API adapter can
// atomically materialise the same manifest + generation envelope.
const zoneSource = await loadZoneSourceProfile(zoneSourceRoot, zoneSourceProfileId);
const liveCache = createCacheStore("live", config.cacheDir, true);
const offlineSnapshot = config.offlineSnapshotDir ? createCacheStore("offline-snapshot", config.offlineSnapshotDir, false) : null;
const inflightWrites = new Map();
@@ -49,6 +61,13 @@ const server = createServer(async (request, response) => {
if (requestUrl.pathname === "/api/map/admin/cesium-ion" && ["GET", "PUT"].includes(request.method || "")) {
return await serveCesiumIonAdmin(request, response, requestUrl.pathname);
}
if (requestUrl.pathname === `/internal/zone-sources/v1/profiles/${encodeURIComponent(zoneSourceProfileId)}/current`) {
if (!["GET", "HEAD"].includes(request.method || "")) {
response.setHeader("Allow", "GET, HEAD");
return writeJson(response, 405, { ok: false, error: "zone_source_method_not_allowed" });
}
return serveZoneSourceGeneration(request, response);
}
if (!isAllowedRequest(request)) return writeJson(response, 401, { ok: false, error: "map_gateway_auth_required" });
if (requestUrl.pathname === "/healthz" && request.method === "GET") {
@@ -61,6 +80,15 @@ const server = createServer(async (request, response) => {
ionConfigured: Boolean(activeCesiumIonToken),
assetAllowlist: [...config.assetAllowlist].map(Number).sort((left, right) => left - right),
anonymousAccess: config.allowAnonymous,
zoneSource: {
profileId: zoneSourceProfileId,
authorityId: zoneSource.generation.authorityId,
datasetId: zoneSource.generation.datasetId,
sourceRevision: zoneSource.generation.sourceRevision,
contentDigest: zoneSource.generation.contentDigest,
sourceZoneCount: zoneSource.generation.metadata.sourceZoneCount,
publishedZoneCount: zoneSource.generation.metadata.publishedZoneCount,
},
});
}
@@ -97,11 +125,27 @@ server.listen(config.port, "0.0.0.0", () => {
console.log(`NODE.DC Map Gateway listening on http://0.0.0.0:${config.port}`);
console.log(`Live map cache: ${config.cacheDir} (${config.mode}, max ${Math.round(config.maxCacheBytes / 1024 / 1024)} MB)`);
if (offlineSnapshot) console.log(`Offline map snapshot: ${config.offlineSnapshotDir} (read-only)`);
console.log(`Zone source: ${zoneSourceProfileId}@${zoneSource.generation.sourceRevision} (${zoneSource.generation.metadata.publishedZoneCount} zones)`);
});
process.on("SIGTERM", () => server.close());
process.on("SIGINT", () => server.close());
function serveZoneSourceGeneration(request, response) {
if (request.headers["if-none-match"] === zoneSource.etag) {
response.writeHead(304, { ETag: zoneSource.etag, "Cache-Control": "private, max-age=60" });
return response.end();
}
response.writeHead(200, {
"Content-Type": "application/json; charset=utf-8",
"Content-Length": zoneSource.body.byteLength,
"Cache-Control": "private, max-age=60",
ETag: zoneSource.etag,
"X-Content-Type-Options": "nosniff",
});
return response.end(request.method === "HEAD" ? undefined : zoneSource.body);
}
async function readConfig() {
const mode = String(process.env.MAP_CACHE_MODE || "readwrite").trim().toLowerCase();
if (!["readwrite", "readonly", "offline"].includes(mode)) throw new Error("invalid_map_cache_mode");