尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Mobile-first Next.js app (App Router, TypeScript strict, Supabase, Tailwind),
usable both as a normal website and as a Telegram Mini App, letting Ukrainians
in Spain search official temporary-protection locations by province and see
dated community reports of what documents each office actually asked for.
See docs/SPEC.md for the full product/domain specification this app
implements, and docs/BOTFATHER.md for the Telegram bot/Mini App setup
checklist.檢視完整 README ↗Mobile-first Next.js app (App Router, TypeScript strict, Supabase, Tailwind), usable both as a normal website and as a Telegram Mini App, letting Ukrainians in Spain search official temporary-protection locations by province and see dated community reports of what documents each office actually asked for.
See docs/SPEC.md for the full product/domain specification this app
implements, and docs/BOTFATHER.md for the Telegram bot/Mini App setup
checklist.
npm install
.env.example to .env.local and fill in:
NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY,
SUPABASE_SERVICE_ROLE_KEY — from Project Settings → API Keys
(Supabase is retiring the old "anon"/"service_role" JWT pair for
"Publishable"/"Secret" keys — see the comment in .env.example for
which goes where; the variable names here don't change either way).supabase/migrations/0001_*.sql through
0008_*.sql) — via the Supabase CLI (supabase db push, once the project
is linked) or by pasting each file into the SQL Editor in the dashboard,
in filename order.seed/locations.csv:
SUPABASE_URL=<project-url> SUPABASE_SERVICE_ROLE_KEY=<service-role-key> npm run seed
This is idempotent (safe to re-run against an unchanged database — see the
caveat in scripts/seed.ts's header about re-running after moderation).
Re-running after the official list changes also hides the locations it
dropped; they keep their reports and can be re-published by a moderator.Follow docs/BOTFATHER.md, then fill in TELEGRAM_BOT_TOKEN,
NEXT_PUBLIC_TELEGRAM_BOT_USERNAME, NEXT_PUBLIC_TELEGRAM_MINI_APP_NAME in
.env.local.
NEXT_PUBLIC_SITE_URL — your dev/prod URL.OFFICIAL_INFO_URL — a real link to official government information;
never invent this.PRIVACY_CONTROLLER_NAME, PRIVACY_CONTACT_EMAIL — the real data
controller's name and contact email. The production build fails if
either is unset (see src/lib/config.ts getPrivacyConfig()); in
development, /privacy shows a "TODO: not configured" banner instead.DEV_LOGIN_ENABLED — true to enable GET /api/auth/dev?user=1|2 for
testing without a real Telegram login (only takes effect outside
production regardless of this flag — see "Dev login" below).npm run dev
Open http://localhost:3000.
This was built and tested in a sandbox with no Docker daemon and no way to
fetch the PostgREST/GoTrue binaries the Supabase CLI's supabase start needs
— npx supabase start fails there with a Docker-socket connection error.
Everything that only needs Postgres itself (not the full Supabase stack) was
instead verified against a plain local PostgreSQL 16 instance:
createdb tpd_test
psql -d tpd_test -f supabase/tests/00_supabase_stub.sql # NEVER run against a real Supabase project — see its header
for f in supabase/migrations/*.sql; do psql -d tpd_test -v ON_ERROR_STOP=1 -f "$f"; done
psql -d tpd_test -v ON_ERROR_STOP=1 -f supabase/tests/01_load_fixture_seed.sql
00_supabase_stub.sql provides a minimal auth.users table, auth.uid()
function and anon/authenticated roles — just enough to exercise RLS and
the matching function with real SQL, without GoTrue/PostgREST. This is how
every acceptance criterion under "Data", "Search and matching", "Reports and
moderation" and most of "Security and privacy" in docs/SPEC.md was actually
verified (see the milestone commits for specifics, including two real bugs
this caught: flags_promote_to_flagged() needing SECURITY DEFINER, and a
missing location_procedures INSERT grant).
What this setup cannot verify: anything requiring real GoTrue-issued
JWTs/sessions or a live HTTP PostgREST endpoint — i.e. npm run dev actually
rendering pages against real data, and the Telegram auth bridge's
generateLink/verifyOtp exchange end-to-end. Those need either
Docker + the Supabase CLI, or a real hosted Supabase project. If you have
either, prefer supabase start && supabase db reset over the manual steps
above — supabase db reset applies supabase/migrations/ automatically.
npm run lint # eslint (Next.js config)
npm run build # production build; also where "/" client-JS budget is enforced
npm test # vitest: pure-function/unit tests, no database needed
npm run test:db # vitest: DB integration tests — needs TEST_DATABASE_URL
# (defaults to the Supabase CLI's local port 54322;
# point it at the plain-Postgres setup above instead
# with e.g. TEST_DATABASE_URL=postgresql://user:[email protected]:5432/tpd_test)
npm run report:home-bundle # prints "/"'s gzipped client-JS size after a build
.env.example in Project Settings → Environment
Variables (for Production and Preview, if you want preview
deployments to work) — SUPABASE_SERVICE_ROLE_KEY and
TELEGRAM_BOT_TOKEN must be added as server-only (never exposed to the
client; Vercel does this automatically for vars without the
NEXT_PUBLIC_ prefix).NEXT_PUBLIC_SITE_URL to the production domain, then update the
Mini App's Web App URL and the Login Widget's domain in @BotFather to
match (docs/BOTFATHER.md steps 2 and 5).PRIVACY_CONTROLLER_NAME/PRIVACY_CONTACT_EMAIL being unset will
fail the build here, by design.See docs/BOTFATHER.md — bot creation, Mini App registration, menu button,
/start, and linking the Login Widget's domain.
There is no admin UI in this app (out of scope, per docs/SPEC.md) —
everything below happens in the Supabase dashboard's Table Editor / SQL
Editor.
locations where moderation_status = 'pending'):
either a conflict seed row needing a phone call to verify (see
seed/VERIFICATION.md), or a user submission (verification_status = 'user_submitted'). Check it, then set moderation_status = 'published'
(or 'rejected').location_suggestions where status = 'pending'): compare current_value (a snapshot from submit time) against
proposed_value. If you accept it, manually update the corresponding
column on the locations row, then set the suggestion's status to
'approved' (this is a manual two-step edit — there is no auto-apply, per
spec: "no import, bulk-insert... path exists for any role, including
moderators").moderation_status = 'flagged', reached
automatically at 3 distinct flaggers): review, then set to 'published'
(restore) or 'hidden'. Never gets there automatically from 'hidden'.policy_changes once a change's
effective_date is confirmed from an official source — never invent a
date. This immediately affects the matching function's "До зміни правил"
labelling and default counts for older reports (see
supabase/migrations/0007_matching.sql). The military-obligation
requirement mentioned in content/legal-notice.uk.md is exactly the kind
of change this table exists for.update profiles set role = 'moderator' where id = '<uuid>';. There is no
self-service path to this role.Cited inline in the relevant source files; collected here per the build prompt's requirement.
Telegram (validation algorithms — src/lib/telegram/):
initData validation: https://core.telegram.org/bots/webapps#validating-data-received-via-the-mini-appSupabase (the Telegram→Supabase-session auth bridge — src/lib/telegram/authBridge.ts):
admin.generateLink: https://supabase.com/docs/reference/javascript/auth-admin-generatelinkverifyOtp: https://supabase.com/docs/reference/javascript/auth-verifyotp@supabase/ssr cookie pattern) — src/lib/supabase/server.ts, src/proxy.ts: https://supabase.com/docs/guides/auth/server-side/nextjsNetwork access to core.telegram.org and supabase.com was blocked by this
sandbox's egress proxy, so these algorithms/APIs were corroborated via
multiple independent secondary sources (community write-ups reproducing the
official pseudocode verbatim) rather than a direct fetch of the pages above,
and the exact verifyOtp parameter shape was additionally checked directly
against the installed @supabase/auth-js TypeScript types (see the comment
in authBridge.ts) rather than trusted from a blog post. Before shipping
this to production, fetch both doc pages directly and diff against the
algorithms implemented here — they are stable, well-known algorithms, but
this was not independently re-verified against the live pages in this
environment.
npm run dev against a live Supabase project (no
Docker/Supabase CLI, no external Supabase project credentials in this
sandbox) — see "Local development" above for exactly what was and wasn't
verified.generateLink/verifyOtp exchange was checked
against the installed SDK's TypeScript types and is expected to work per
the SDK's documented contract, but was not exercised against a real
Supabase Auth server (needs a real project + a real or synthetic Telegram
login).