Files
Ten31-Portal/frontend/public/sw.js
T
Jonathan Kirkwood ebafcf19d9 0.2.43: historical NAV backfill without touching current holdings
The batch history import now also records each quarter's NAV in the
fund's valuation history: the old file's HLD rows are matched by issuer
and security name against the book as it exists today, matched rows
write that quarter's valuations, unmatched rows are counted and
reported, and nothing outside the round is created or modified. A
manually signed quarter is never overwritten.

The single-file wizard automatically takes the same history-only path
when the file is older than the fund's newest round. Previously that
import would regress position cost basis to the old file's values and
resurrect since-exited positions, corrupting the fund's Invested total.
2026-08-11 12:32:57 -05:00

57 lines
1.7 KiB
JavaScript

// Ten31 Portal service worker. Deliberately conservative so it never serves a stale app:
// - navigations are network-first (always get the latest index.html), cache only as offline fallback
// - content-hashed /assets/* are cache-first (immutable, safe forever)
// - /api/* is never cached
// Bump CACHE on each release so old entries are purged.
const CACHE = 'ten31-portal-0.2.43'
self.addEventListener('install', () => self.skipWaiting())
self.addEventListener('activate', (event) => {
event.waitUntil(
(async () => {
const keys = await caches.keys()
await Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
await self.clients.claim()
})(),
)
})
self.addEventListener('fetch', (event) => {
const req = event.request
if (req.method !== 'GET') return
const url = new URL(req.url)
if (url.origin !== self.location.origin) return
if (url.pathname.startsWith('/api/')) return
if (req.mode === 'navigate') {
event.respondWith(
(async () => {
try {
const fresh = await fetch(req)
const cache = await caches.open(CACHE)
cache.put('/', fresh.clone())
return fresh
} catch {
const cache = await caches.open(CACHE)
return (await cache.match('/')) || Response.error()
}
})(),
)
return
}
if (url.pathname.startsWith('/assets/')) {
event.respondWith(
(async () => {
const cache = await caches.open(CACHE)
const hit = await cache.match(req)
if (hit) return hit
const res = await fetch(req)
if (res.ok) cache.put(req, res.clone())
return res
})(),
)
}
})