尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A kiosk dashboard for one stretch of coast: a live map of the ships and
aircraft passing through it and of what is happening on its roads, plus
weather, aurora and tide pages that cycle on their own on a wall display.查看完整 README ↗A kiosk dashboard for one stretch of coast: a live map of the ships and aircraft passing through it and of what is happening on its roads, plus weather, aurora and tide pages that cycle on their own on a wall display.
The frontend is vanilla TypeScript -- no framework, its own small reactive
primitives -- built with Vite, with Leaflet for the map. Behind it sits a
Node/TypeScript backend-for-frontend on Fastify. It proxies exactly one
upstream -- the nesthus.no Laravel API, which serves weather, tide,
aurora and the cameras -- and calls three providers directly for the
live data upstream has nothing for: BarentsWatch (AIS), an ADS-B aggregator
(aircraft) and Statens vegvesen (road notices and road cameras). It holds
the API credentials, caches the responses and validates every payload with
Zod before the browser sees it.
A live instance runs at area.nesthus.no.
See docs/ARCHITECTURE.md for how the pieces fit together, docs/ROADMAP.md
for the phase plan, and docs/adr/ for the reasoning behind the main design
decisions.
.env. Without them the app
runs and those pages simply report that they are not configured:
BARENTSWATCH_CLIENT_ID / _SECRET -- AIS ship positions.OPENSKY_CLIENT_ID / _SECRET -- aircraft, if ADSB_PROVIDER=opensky;
the default adsblol needs no credentials.CARTO_API_KEY -- unwatermarked dark basemap tiles.ENTUR_CLIENT_NAME
identifies this app to the API via the ET-Client-Name header, in
place of a credential -- set to something descriptive of the
deployment, not left blank.MET_USER_AGENT including contact information.MET_USER_AGENT as MET Alerts above to identify this app on every
request -- there is no separate GBIF-specific variable.SETTINGS_PASSWORD (at least 16 characters) is required -- the BFF
refuses to start without it. It is the one passphrase that authorises
edits from the settings page; reading is public.npm ci
cp .env.example .env # then fill in the values
.env is never committed. Every key in .env.example is documented there.
npm run dev # the BFF and the Vite dev server together
The BFF listens on 127.0.0.1:8141 (PORT/HOST in .env) and Vite
proxies /api to it. It must never bind 0.0.0.0: expose it through a
reverse proxy instead.
npm run build # frontend via Vite, server via tsc, both into dist/
npm start # serve the built app from the BFF
npm run check # typecheck, lint, format:check, test
Each stage is also available on its own (npm run typecheck, lint,
format:check, test, plus test:watch, lint:fix, format).
The app ships as a single-service Docker Compose stack: one image containing
the built frontend and the BFF that serves it, published on 127.0.0.1:8141
for a reverse proxy to terminate TLS in front of.
make init # create .env if absent, then fill it in
docker compose up -d --build
Settings persist in ./data/. make check verifies the published port is
loopback-only and the container is healthy; make deploy pulls, rebuilds and
brings the stack up. The Makefile has the rest (build, up, down,
restart, logs, shell).
Hostname, DNS and certificate setup -- the parts that need a human -- are in
deploy/manual-steps.md.
MIT.
The road notices, road cameras and traffic-sign artwork on the map come from Statens vegvesen under NLOD, which requires attribution:
Inneholder data under norsk lisens for offentlige data (NLOD) tilgjengeliggjort av Statens vegvesen.
The sign faces are vendored in src/web/pages/map/signs/; that
directory's README.md records where they came from, what was changed
and why they are only ever drawn small. The map footer carries the short
form, Data: Statens vegvesen.
The transit layer's buses and ferries come from Entur's realtime API,
keyless but requiring every caller to identify itself (the
ET-Client-Name header, set from ENTUR_CLIENT_NAME). Licensed under
NLOD, the same licence as Statens vegvesen's data above. The map footer
carries Data: Entur.
The warnings layer merges MET Norway's Alerts (weather warnings: gale,
storm surge, polar low, ice, forest fire) and NVE Varsom's avalanche
danger forecasts, both keyless. MET's terms of use require a descriptive
User-Agent with contact information (MET_USER_AGENT). MET Norway's
data is licensed under NLOD and NVE Varsom's under CC BY 4.0. The map
footer carries Data: MET Norway / NVE.
The species layer's sightings come from GBIF's keyless occurrence search,
which republishes Norwegian citizen-science data (mostly Artsobservasjoner
records). GBIF asks for no credential of its own, but the server identifies
itself on every request with the same MET_USER_AGENT configured for MET
Alerts above, rather than sending no identifying User-Agent at all. Licence
varies per record -- CC BY 4.0 and CC BY-NC 4.0 have both been
observed -- so each sighting's own licence is shown in its popup rather
than a single blanket statement here. The map footer carries Data: GBIF.