Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Compare ticket prices and filter nightlife events in New York from one feed
AI summary · website and README
LifestyleTypeScript · PLpgSQLGitHub @noct-nightOnlineOwner 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.
One feed for New York nightlife. NOCT pulls club nights, raves and day parties from every platform that
lists them — Resident Advisor, DICE, venue calendars, Ticketmaster (and EDMTrain if licensed) — dedupes
them into one event per night per room, shows every ticket price side by side, and tags each night with a
genre and a vibe.
NOCT is a working name. Nothing is attached to it yet.Read the full README ↗One feed for New York nightlife. NOCT pulls club nights, raves and day parties from every platform that lists them — Resident Advisor, DICE, venue calendars, Ticketmaster (and EDMTrain if licensed) — dedupes them into one event per night per room, shows every ticket price side by side, and tags each night with a genre and a vibe.
NOCT is a working name. Nothing is attached to it yet.
index.html the app (mobile-first, 440px). Loads /api/feed; falls back to the sample weekend
studio/ the Instagram review page, served gated by api/studio.ts (never as a static file)
api/ Vercel Functions
feed.ts GET /api/feed?from&to → events/venues/days in the shape the UI expects
(&counts=1 → per-night counts only, what the month calendar draws)
recommend.ts GET /api/recommend → nights picked from the caller's own going/saved history
ingest/[source].ts GET|POST /api/ingest/ra|dice|elsewhere|…|all (Bearer CRON_SECRET)
enrich.ts POST /api/enrich — genre/vibe pass over new/changed events
health.ts GET /api/health — last run per source
studio.ts GET /studio — the Instagram review page, behind a studio session
session.ts POST|DELETE /api/session — sign in to the studio, or out
posts.ts the queue's data API: draft a weekend, edit a caption, approve or pass
img.ts GET /api/img — one promoter flyer, treated, as JPEG (host allowlist)
render.ts GET composes one 1080x1350 slide from a signed URL; POST signs a deck
publish.ts POST /api/publish — puts one approved deck on Instagram. Manual, never cron
GET — preflight: does the credential work, how many posts left today
src/
sources/ one adapter per source (RA, DICE, Elsewhere, Good Room, Public Records, SILO, Ticketmaster, EDMTrain): fetch + normalise, no DB
ingest/ runner: adapter → upsert_listing() → resolve_pending() → tombstone_sweep()
enrich/ taxonomy, crosswalk, rules engine, Claude reconciler
feed/ read model → UI shape, and the recommendation scorer's caller
post/ Instagram: slide templates (satori), tones/veil/grain (sharp), flyer treatments,
weekend drafting, caption house rules, the queue store, the Instagram API
client, and the 60-day token refresh that keeps a weekly post unattended
lib/ http (polite fetch, block detection), time (NY ⇄ UTC), normalize, db
supabase/migrations/ Postgres schema: listings, events, venues/aliases, resolution SQL, enrichment,
app tables, views + RLS, pg_cron schedules
tests/ vitest — unit tests on real captured payloads; DB tests; opt-in live tests
docs/ DATA_SOURCES.md (terms + decisions), OPERATIONS.md, GENRE_VIBE.md,
RECOMMENDATIONS.md, FRONTEND.md, INSTAGRAM.md, sources/*.md
NormalizedListing
rows. The runner upserts them (upsert_listing, keyed by (source, source_id)), tracks first/last
seen, content changes and disappearances (tombstones), and stores every price tier.resolve_listing() links each listing to a canonical event: hard cross-references
first (a venue page linking a DICE id), then venue family + nightlife date + trigram title + lineup
overlap. Grey-zone matches land in match_candidate for review; canonical fields are recomputed from
the highest-priority live listing (refresh_event).event_tag)./api/feed reads event_feed (RLS-guarded view) and returns the weekend in the UI's
shape, cached at the edge for five minutes.npm install
cp .env.example .env # fill DATABASE_URL (local Postgres is fine) and optional keys
bash scripts/db-local.sh noct # creates the DB and applies every migration
npm run fetch -- ra --limit 5 # dry-run one adapter (no DB)
DATABASE_URL=postgresql://localhost:5432/noct npm run ingest -- ra elsewhere publicrecords goodroom
DATABASE_URL=postgresql://localhost:5432/noct npm run enrich -- --limit 20 # rules-only unless an LLM key is set (docs/GENRE_VIBE.md → Provider options)
npm test # unit + DB tests (DB tests skip without DATABASE_URL); NOCT_LIVE=1 adds live tests
npx vercel dev # serves index.html + /api/*
supabase link --project-ref <ref>, supabase db push. Copy the
Supavisor transaction pooler URL (IPv4, port 6543) into DATABASE_URL.vercel link, set env vars from .env.example (DATABASE_URL, CRON_SECRET, keys),
vercel deploy --prod. vercel.json registers the daily fallback crons (Hobby limit).vercel_base_url and cron_secret into app_setting so pg_cron can call
/api/ingest/* every few hours (docs/OPERATIONS.md)./api/ingest/ra?limit=5 once and read /api/health. If a source shows BLOCKED:, that host
rejects datacenter traffic — see docs/DATA_SOURCES.md; NOCT does not work around blocks.Read docs/DATA_SOURCES.md. Short version: RA's GraphQL endpoint is the canonical record (their terms
restrict automated commercial extraction — ask for written permission), DICE runs only with a key DICE
issues to you, EDMTrain is off unless licensed, venue feeds are on, Ticketmaster is on with a free key.
NOCT never solves bot challenges, proxies, or borrows credentials found on other sites.
Verified locally end to end on PostgreSQL 14: one fresh apply of all eight migrations, 250 tests
(npm test, DB-backed ones included), a real ingest of RA + Elsewhere + Public Records + Good Room for
the next 7 nights (≈230 listings → ≈210 events, 15 cross-source merges, 12 grey-zone matches queued for
review), a rules-only enrichment pass, and /api/feed JSON for a Friday–Sunday range. Not yet exercised:
a real Vercel deployment, pg_cron on Supabase, the live Claude call (needs ANTHROPIC_API_KEY), DICE /
Ticketmaster / EDMTrain with real keys.
0005_app.sql) but the
UI is not wired to Supabase Auth (Instagram is not a Supabase provider — see docs/FRONTEND.md).not_electronic flag are what fix that.docs/GENRE_VIBE.md) but not implemented.venue.needs_review)./studio. Venue slides still need photographs. Using promoter flyers in NOCT's own marketing posts (rather
than to display listings) is a rights question both RA and DICE restrict — see docs/INSTAGRAM.md.NOCT_CITIES); San Francisco, Chicago, Miami, DC, Detroit, Toronto, London, Berlin are registered (src/lib/cities.ts) and switch on by adding them to NOCT_CITIES. Venue-direct feeds and the venue seed are New York only, so other cities rely on RA (+ 19hz where it has a list).Open an issue, or leave comments on the relevant line.