openvibers/openvibe.tools Commits

Tools: food.openvibe.tools sends people to OpenVibe.Food (301); the food finder API stays (#72)

OP OpenVibers committed 28 days ago · 765798c6e6 · 6 files, +26 −13

The old Food.OpenVibe page duplicated openvibe.food (its own canonical). The food tools moved there (food banks and
budget grocers near you, the food list, meal plans, pantry, recipes), as the owner asked, so the page and its old
paths now redirect permanently to https://openvibe.food/ (OV_FOOD_PUBLIC_URL); the JSON routes and the tool
registry keep answering. Cross links on maps and audio and the Maps & Food family point at openvibe.food.

Changes

ddiff --git a/README.md b/README.md
iindex 9c119ca..3ccd4c6 100644
---- a/README.md
++++ b/README.md
@@@ -56,7 +56,7 @@ apps/
├── gateway # apex (server-rendered index, family + tool pages, catalog.json), the tool registry
│ # and host roles, Net.OpenVibe + Dev.OpenVibe tools, proxy to the satellites
├── maps # Maps.OpenVibe — survival map for North America
--├── food # Food.OpenVibe — grocery / food bank finder (proxies maps backend)
++├── food # the food finder API (proxies maps backend); its page moved to OpenVibe.Food (301 to openvibe.food)
├── img # Img.OpenVibe — image converter & processing tools
├── yt # YT.OpenVibe — YouTube downloader
├── audio # Audio.OpenVibe — audio converter & effects
ddiff --git a/apps/audio/public/index.html b/apps/audio/public/index.html
iindex bca2c7e..120484a 100644
---- a/apps/audio/public/index.html
++++ b/apps/audio/public/index.html
@@@ -339,9 +339,9 @@
<span class="cross-icon"><i class="fa-solid fa-map-location-dot"></i></span>
<span class="cross-info"><span class="cross-name">Maps.OpenVibe</span><span class="cross-desc">Camps, resources & shelters</span></span>
</a>
-- <a class="cross-card" href="https://food.openvibe.tools">
++ <a class="cross-card" href="https://openvibe.food">
<span class="cross-icon"><i class="fa-solid fa-utensils"></i></span>
-- <span class="cross-info"><span class="cross-name">Food.OpenVibe</span><span class="cross-desc">Food banks & meal planner</span></span>
++ <span class="cross-info"><span class="cross-name">OpenVibe.Food</span><span class="cross-desc">Food banks, cheap groceries & meal plans</span></span>
</a>
</div>
</section>
ddiff --git a/apps/food/server/index.js b/apps/food/server/index.js
iindex cd372e2..1df5565 100644
---- a/apps/food/server/index.js
++++ b/apps/food/server/index.js
@@@ -1,6 +1,9 @@
/**
-- * food.openvibe.tools — Lightweight frontend server
-- * Proxies food API calls to openvibe-maps backend (port 4010)
++ * food.openvibe.tools — the food finder's API (proxied to the openvibe-maps backend, port 4010).
++ *
++ * The page moved to OpenVibe.Food (openvibe.food: food banks and budget grocers near you, the food list, meal plans,
++ * pantry, recipes): a person opening food.openvibe.tools is sent there with a 301. The JSON routes stay, as every
++ * tool's do (the open tools registry, ADR-027).
*/
require('dotenv').config();
const express = require('express');
@@@ -14,7 +17,7 @@ const cookieParser = require('cookie-parser');
// ── Analytics ────────────────────────────────────────────────
const { AnalyticsTrackerPg } = require('openvibe-shared/analytics/pg'); // ADR-021: no IP/user id, route templates, raw rows pruned after 30 days, Sec-GPC/DNT not recorded
const { requireInternalAccess } = require('../../_shared/internal-token');
--const { hostGuard, stampedPage } = require('../../_shared/host-role');
++const { hostGuard } = require('../../_shared/host-role');
const { createToolsApi, exceptRegistry } = require('../../_shared/tools/http');
const { createLocalRegistry, requiresStatus } = require('../../_shared/tools/local');
const { createGuard, TRUST_PROXY } = require('../../_shared/guard');
@@@ -116,8 +119,10 @@ app.use(analytics.middleware());
// page's canonical / og:url / JSON-LD follow it; aliases are redirected; other hosts go to the tools index.
const HOST = 'food.openvibe.tools';
app.use(hostGuard({ knows: (h) => h === HOST }));
--const sendIndex = stampedPage(path.join(__dirname, '..', 'public', 'index.html'), HOST);
--app.get(['/', '/index.html'], sendIndex);
++// The page is OpenVibe.Food's now; the JSON routes below stay for whoever calls them.
++const FOOD_URL = (process.env.OV_FOOD_PUBLIC_URL || 'https://openvibe.food').replace(/\/+$/, '');
++const toFood = (req, res) => res.redirect(301, `${FOOD_URL}/`);
++app.get(['/', '/index.html'], toFood);
// Static files
app.use(express.static(path.join(__dirname, '..', 'public'), { maxAge: '1d', index: false }));
@@@ -163,8 +168,8 @@ app.get('/api/internal/analytics/bots', internalAccess, async (req, res) => {
catch (err) { res.status(500).json({ ok: false, error: err.message }); }
});
--// SPA fallback
--app.get('*', (req, res) => sendIndex(req, res));
++// What used to be the page's own paths go to OpenVibe.Food as well (the API answers JSON 404s).
++app.get('*', (req, res) => (req.path.startsWith('/api/') ? res.status(404).json({ error: 'Not found' }) : toFood(req, res)));
const server = app.listen(PORT, '127.0.0.1', () => {
console.log(`[Food.OpenVibe] 🍽️ food.openvibe.tools listening on 127.0.0.1:${PORT}`);
ddiff --git a/apps/food/test/maps-forwarding.test.js b/apps/food/test/maps-forwarding.test.js
iindex 227a740..6dc631f 100644
---- a/apps/food/test/maps-forwarding.test.js
++++ b/apps/food/test/maps-forwarding.test.js
@@@ -20,6 +20,14 @@ const { startApp } = require('../../_shared/test/spawn');
const other = await ask('203.0.113.2');
assert.strictEqual(other.status, 200, 'a second visitor has their own bucket');
++ // The page moved to OpenVibe.Food: a person is sent there; the JSON routes stay.
++ for (const p of ['/', '/index.html', '/food-banks']) {
++ const r = await fetch(`${food.base}${p}`, { redirect: 'manual', headers: { Host: 'food.openvibe.tools' } });
++ assert.strictEqual(r.status, 301, p);
++ assert.strictEqual(r.headers.get('location'), 'https://openvibe.food/', p);
++ }
++ assert.strictEqual((await fetch(`${food.base}/api/nothing-here`)).status, 404, 'an unknown API path is a JSON 404, not a redirect');
++
const src = (app) => fs.readFileSync(path.join(__dirname, '..', '..', app, 'server', 'index.js'), 'utf8');
assert.match(src('maps'), /app\.set\('trust proxy', TRUST_PROXY\)/, 'maps trusts one forwarded hop, on loopback only');
assert.match(src('food'), /app\.set\('trust proxy', TRUST_PROXY\)/);
@@@ -28,5 +36,5 @@ const { startApp } = require('../../_shared/test/spawn');
await food.kill();
await maps.kill();
}
-- console.log('food → maps forwards the visitor address; maps limits per person: all checks passed');
++ console.log('food → maps forwards the visitor address; maps limits per person; the page redirects to openvibe.food: all checks passed');
})().catch((err) => { console.error(err); process.exit(1); });
ddiff --git a/apps/gateway/server/registry/families.js b/apps/gateway/server/registry/families.js
iindex 1ca8df3..c488e2f 100644
---- a/apps/gateway/server/registry/families.js
++++ b/apps/gateway/server/registry/families.js
@@@ -90,7 +90,7 @@ const FAMILIES = [
{
id: 'places', name: 'Maps & Food', icon: 'map', path: '/maps-and-food', hub: null, hubAliases: [], port: null,
tagline: 'Find water, shelter, supplies and somewhere to eat',
-- description: 'Two practical maps. The survival map shows drinking water, public toilets, shelters, hospitals, fuel and other essentials near any place on earth. The food finder shows restaurants, cafes, markets and food banks around you.',
++ description: 'Two practical maps. The survival map shows drinking water, public toilets, shelters, hospitals, fuel and other essentials near any place on earth. The food finder (now OpenVibe.Food, at openvibe.food) shows food banks, budget grocers and markets around you, with meal plans and a pantry.',
intro: 'Both tools use open map data. Allow location access or search for a town, then filter the map to the kind of place you need.',
faq: [
['Where does the map data come from?', 'OpenStreetMap and other open datasets, maintained by volunteers around the world. Coverage is best in towns and cities.'],
ddiff --git a/apps/maps/public/index.html b/apps/maps/public/index.html
iindex 5f54e15..e70efa2 100644
---- a/apps/maps/public/index.html
++++ b/apps/maps/public/index.html
@@@ -416,7 +416,7 @@
service: 'maps', variant: 'compact', mount: '#ov-footer', apiBase: 'https://openvibe.network',
links: [{ heading: 'Maps.OpenVibe', items: [
{ name: 'Survival map', url: 'https://maps.openvibe.tools' },
-- { name: 'Food.OpenVibe', url: 'https://food.openvibe.tools' },
++ { name: 'OpenVibe.Food', url: 'https://openvibe.food' },
{ name: 'All tools', url: 'https://openvibe.tools' },
] }],
});