Maintainer Reference

Artist Discovery Portal

An artist discovery portal - connecting singers and instrumentalists through a beautiful, accessible and multilingual platform.

Speciality colour themingIndic script supportPWA-readyNLP-free searchMagic-link authMulti-region configPrivacy-aware analytics

1. Speciality-based colour theming

Every artist profile is visually themed by their instrument - instantly recognisable at a glance.

Illustrative cards (palette + directory layout)

Two specialities

E

Example: multi-instrumentalist

ViolinMorsing

Fictional example - palette only

Three specialities (maximum)

T

Example: trio of roles

VocalViolinMridangam

Fictional example - palette only

Registered artists from the directory

How it works: Each speciality (Vocal, Violin, Mridangam, Veena…) has a unique hex colour in the admin-managed palette (mirrored in lib/speciality-theme.ts for tests). Artists can pick up to three specialities on registration; each tag uses its stored colour, and the card header uses those same values (solid for one colour, diagonal linear-gradient when several distinct colours apply). Single-speciality artists get a solid colour header. All text colours are WCAG AA compliant (≥4.5:1 contrast ratio - verified by property-based tests).

2. Indic script & Unicode support

Artists can write their bio and other profile text in any Indic script - Tamil, Kannada, Telugu, Malayalam, Devanagari and more.

Tamil

கர்நாடக இசை என் உயிர். சிறு வயதிலிருந்தே வீணை வாசிக்கக் கற்றுக்கொண்டேன்.

Malayalam

കർണ്ണാടക സംഗീതം എന്റെ ജീവിതത്തിന്റെ ഭാഗമാണ്. ഞാൻ ചെറുപ്പം മുതൽ മൃദംഗം പഠിച്ചു.

Telugu

కర్ణాటక సంగీతం నా జీవితంలో అంతర్భాగం. నేను చిన్నప్పటి నుండి వీణ నేర్చుకున్నాను.

Kannada

ಕರ್ನಾಟಕ ಸಂಗೀತ ನನ್ನ ಜೀವನದ ಭಾಗ. ನಾನು ಚಿಕ್ಕಂದಿನಿಂದ ವೀಣೆ ಕಲಿತೆ.

Hindi

कर्नाटक संगीत मेरे जीवन का अभिन्न अंग है। मैंने बचपन से मृदंगम सीखा।

Mixed

My journey in music began in Chennai and continues in Amsterdam - classical vocals remain my anchor.

How it works: The Tiptap rich-text editor accepts direct Unicode keyboard input for all Indic scripts. The Google Fonts Noto family (loaded with font-display: swap) provides full glyph coverage with no tofu (□) characters. Correct lang attributes are set on all user-generated content elements for screen readers and browser shaping engines. Mixed-script content (English + Tamil + Malayalam in the same paragraph) renders cleanly.

4. Magic-link authentication

No passwords to remember. We email you a time-limited link instead.

📧

Step 1

Enter your email

Open the sign-in page and type the same email you used when you registered. We send a single-use sign-in link to that inbox.

✉️

Step 2

Use the link in your email

Tap the link in the message from us. If nothing shows up within a minute, check Spam, Promotions, or similar folders in your mail app.

Step 3

Tap Continue to finish

Your browser opens a short confirmation screen. Press Continue once to complete sign-in. Use Log out in the header or dashboard when you finish on a shared device.

Security (technical): Magic-link tokens are stored as SHA-256 hashes; issuing a new link invalidates older unused ones. The email points at /auth/verify?token=…; the page loads on GET only and the browser submits a POST to consume the token so mail previews and prefetch cannot burn the link. Links expire after 72 hours. Successful sign-in sets a 30-day session cookie backed by an HS256 JWT; Edge middleware validates it without a database round-trip on every request. Logout uses POST /api/auth/logout. Admin access matches the signed-in email against the ADMIN_EMAILS environment list. While signed in, a line above the site footer can show your profile display name, session expiry, and for admins (admin) after the name.

5. Collaborations & peer feedback (optional)

Group planning and star ratings after gigs can be enabled per deployment.

On this site, collaboration chats and peer star ratings are turned off. The experience stays focused on discovering artists, reading profiles, and registering - without group threads or post-concert reviews in the UI.

Operators can turn the area back on with the PostHog boolean flag artist-collabs-ratings or the POSTHOG_FLAG_ARTIST_COLLABS_RATINGS / NEXT_PUBLIC_POSTHOG_FLAG_ARTIST_COLLABS_RATINGS env overrides (see env.example).

6. PWA & mobile-first design

Installable on iOS and Android. Offline-capable. All touch targets ≥44×44px.

📱

Installable

Web App Manifest with standalone display mode. Add to home screen on iOS and Android.

📶

Offline-capable

Service Worker caches the app shell and previously loaded artist profiles. Offline indicator shown.

🔔

Push notifications

VAPID-based Web Push when your operator enables browser notifications. Email vs push preferences live under /profile/notifications.

Targets: Lighthouse PWA ≥90 · Performance ≥85 · Accessibility ≥90 (all on mobile profile). All interactive elements have a minimum 44×44 CSS pixel touch target. Semantic HTML throughout.

7. Multi-region extensibility

Deploy for Belgium, Singapore, or any country by swapping a config file - zero code changes.

# .env.local - Netherlands deployment

DEPLOYMENT_REGION=NL
DEPLOYMENT_NAME=Artist Discovery Portal
DEPLOYMENT_LOCALE_PRIMARY=en
DEPLOYMENT_LOCALE_SECONDARY=nl
DEPLOYMENT_MAP_GEOJSON_URL=/geo/netherlands-provinces.geojson
DEPLOYMENT_BRANDING_LOGO_URL=/assets/logo.svg
To deploy for Belgium: swap netherlands-provinces.geojson for a Belgian provinces GeoJSON, set DEPLOYMENT_LOCALE_SECONDARY=fr (or nl), and add French translations to messages/fr.json. The home page map, language switcher, and date formats all update automatically. No application code changes needed.

8. Home spotlight & featured artist

The landing page highlights one vocalist each local calendar day, with room for discovery without crowding the layout.

Daily rotation

The featured slot prefers Vocal artists and falls back to the full directory when needed. Which artist appears advances deterministically by calendar day in the deployment country's timezone (derived from DEPLOYMENT_REGION unless DEPLOYMENT_TIMEZONE is set). Ops can pin a vocalist for a given day via the DailyFeatured table.

Profile photo

The card loads each artist's public profile photo URL (the HTTPS link they saved on their profile), with a coloured initial if the image cannot load. Collab teasers stay hidden while collaborations are turned off for this deployment.

Implementation: getDailyFeaturedArtistForHome() in lib/queries/artists.ts, local-day helpers in lib/local-day.ts, deployment timezone in deployment.config.ts.

9. Admin moderation tools

Full CRUD on artists and specialities, plus registration review and account suspension.

📋

Registration review

Approve or reject applicants with review comments, filters, and clear status handling. Approved artists receive a magic-link login email automatically.

🎵

Artist management

Edit any artist profile, suspend accounts with validation and audit context, delete with cascade (availability, links, collabs).

💬

Collab moderation

Collab and chat moderation UIs stay hidden while the collaboration feature pack is disabled for this deployment.

🎨

Speciality management

Add/edit/delete specialities and their colour palette. Delete guard prevents removing specialities in use.

Access: Admin routes (/admin/*) are protected by Edge middleware. Admin role is granted by listing the artist's email in the ADMIN_EMAILS env var (comma-separated).In dev, use to get an instant admin session.

10. Product analytics & privacy (PostHog)

Optional telemetry with conservative defaults - see /privacy for end-user language.

What is captured

  • Explicit product events plus manual page views (autocapture stays off).
  • Browser traffic in production uses a same-origin /api/ph proxy so ingest hosts are not embedded in the client bundle.
  • Server routes can emit events with artistId as the PostHog distinct id - not email.
  • Post-login redirects add ?ph_identify=1 once to the artist or admin dashboard URL so the client can posthog.identify(artistId, …) and align browser analytics with the same id (query param is stripped on the next navigation; local /api/dev/login does the same in non-production).

Session Replay & choice

  • Session Replay is gated by environment variables; SDK text masking is enabled.
  • Do Not Track and the ph_opt_out cookie are respected on the client.
  • Visitors can use /privacy (opt-in / opt-out) for the full disclosure.
Maintainer docs: repository specs under .kiro/specs/posthog-analytics/ and the operator guide .kiro/steering/posthog-admin-guide.md. Env template: env.example (PostHog block).

11. Tech stack at a glance

Modern, open-source, no usage-limit surprises.

LayerTechnology
FrameworkNext.js 16 (App Router)
HostingCloudflare Workers + OpenNext
LanguageTypeScript
StylingTailwind CSS
DatabasePostgreSQL via Neon
ORMPrisma
AuthCustom magic-link (JWT + Resend)
MediaHTTPS profile assets
Cache/sessionsCloudflare KV (optional)
Rich textTiptap
MapsD3.js + GeoJSON
i18nnext-intl
AnalyticsPostHog (optional)
TestingVitest + fast-check

Maintainer quick links

🛠 Admin dashboard👥 Artist directory📝 Registration form🔗 Magic link login