The community network for Apna Hong Kong — news, magazine, jobs, podcasts, and discussion for the community in Hong Kong.
SocialTypeScript · JavaScriptGitHub @kinghani1OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
The official website and content platform for the Apna Hong Kong Network
community — news, magazine, jobs, podcasts, and discussion, in English, Chinese,
and Urdu, with an admin dashboard for content management.
Version 1.0. For deployment, maintenance, and a full architecture guide,
see PROJECT_HANDOFF.md.Read the full README ↗The official website and content platform for the Apna Hong Kong Network community — news, magazine, jobs, podcasts, and discussion, in English, Chinese, and Urdu, with an admin dashboard for content management.
Version 1.0. For deployment, maintenance, and a full architecture guide, see
PROJECT_HANDOFF.md.
# 1. Install dependencies
npm install
# 2. Create your environment file
cp .env.example .env.local
# then fill in the values (see below)
# 3. Start the dev server
npm run dev
The app runs at http://localhost:3000 and redirects to the default locale
(/en).
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Yes | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Yes | Supabase anonymous (publishable) key |
NEXT_PUBLIC_SITE_URL | Prod | Absolute site URL for SEO metadata, sitemap, and robots (e.g. https://apnahknetwork.com) |
Only the anon key is used — there is no service-role key in the app, and all
data access is enforced by Row Level Security. Environment variables are
validated centrally in config/env.ts.
SQL lives in supabase/:
migrations/0001_initial_schema.sql — tables, keys, constraints, indexes, triggersmigrations/0002_rls_policies.sql — Row Level Security policies + role helpersmigrations/0003_storage.sql — media buckets (images/pdfs/podcasts) + storage RLSseed.sql — minimal development data (two admin accounts + sample content)With the Supabase CLI:
supabase db reset # applies migrations + seed to your local database
Or run the migration files against a hosted project via the SQL editor.
npm run dev # start the dev server
npm run build # production build
npm run start # run the production server
npm run lint # ESLint
npm run format # Prettier (write)
npm run format:check # Prettier (check)
npm run validate:supabase # smoke-test the live DB (schema, RLS, auth, storage)
npm run validate:supabase runs an end-to-end smoke test against the Supabase
project in your environment (or .env.local), using only the anon key plus a
seed admin login — no service-role secret. It verifies the schema is applied,
that RLS enforces published-only public reads and rejects anonymous writes, that
admin login and CRUD work, and that the storage buckets exist. It exits non-zero
on any failure, so it doubles as a post-deploy check. See
scripts/validate-supabase.mjs.
Provision a Supabase project and apply supabase/migrations/*.
Create the two administrator accounts (Supabase Auth) and set their role to
admin in the public.users table.
Configure Storage buckets images, pdfs, podcasts.
Set the environment variables (including NEXT_PUBLIC_SITE_URL).
Run npm run validate:supabase against the project to confirm schema, RLS,
auth, and storage are correctly configured before going live.
Deploy on any Next.js-compatible host (e.g. Vercel):
npm run build
npm run start
Public content pages use ISR/on-demand caching (5-minute revalidate), so content edited in the admin dashboard appears without a redeploy.
Layered, feature-oriented, with a strict dependency direction (UI → services → Supabase):
types/) — hand-written TypeScript entities and
shared primitives (Locale, LocalizedText, PaginatedResult, …).lib/validations/) — one Zod schema per
entity; inferred input types are the write contracts.services/repositories/) — a
generic Supabase-backed data-access layer (CRUD + singletons) behind stable
interfaces. createRepositories(client) is the single wiring point.lib/auth/, lib/supabase/,
proxy.ts) — Supabase SSR sessions, role-aware guards
(requireStaff / requireAdmin), and the request proxy.i18n/, messages/) — locale routing,
request config, and locale-aware navigation.components/, ,
) — a Tailwind-v4 design system, admin dashboard, and public
site. Server Components by default; Client Components only where interactive.app/
[locale]/
(public)/ Public site: home, news, magazine, jobs, podcasts,
discussion, about, contact (+ loading/error/not-found)
(admin)/ Admin: login + protected /dashboard CRUD
robots.ts robots.txt
sitemap.ts sitemap.xml
components/
ui/ Design-system primitives (Button, Card, Badge, …)
layout/ Header, Footer, Container, Section, Navigation
admin/ Dashboard shell, tables, forms, controls
public/ Public content cards, grids, pager, search
config/ Site config, env validation, navigation model
features/
admin/ Admin server actions + entity forms
public/ Public data access (anon repos, safe fetch, helpers)
home/ Homepage CTA section
i18n/ Routing, request config, navigation
lib/
auth/ Auth read/guards/actions/permissions
supabase/ Browser / server / middleware / public clients
validations/ Zod schemas per entity
storage/ Storage buckets + path builders
services/
repositories/ Repository contracts + Supabase implementations
integrations/ Facebook sync contracts (future)
errors.ts RepositoryError / NotImplementedError
types/ Domain models
utils/ Framework-independent helpers (cn)
supabase/ SQL migrations + seed
messages/ Translation catalogs (en / zh / ur)
scripts/ Ops tooling (validate-supabase.mjs smoke test)
These are intentional, documented trade-offs for the 1.0 release — not defects.
The full list, with rationale and effort estimates, is in
PROJECT_HANDOFF.md.
lint + tsc + build and the
validate:supabase smoke test. Unit/e2e coverage is the top maintenance item.components/admin/form/media-upload-field.tsx is a placeholder).reply_count / last_reply_at on discussion threads are not maintained
by a trigger (list views may show stale counts).services/integrations/facebook/).Direct media uploads from the admin UI, richer rich-text editing, UI-string
localization, community discussion accounts, and the Facebook → News sync are
the planned enhancements. See PROJECT_HANDOFF.md.
features/