Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
PN 연감: 우리 폴을 특별하게 만든 인물·이름·순간. 과거 호를 살펴보고 사진을 명예의 전당에 추가
L'annuario storico del PN: volti, nomi e momenti che rendono unico il nostro polo. Sfoglia le edizioni passate e aggiungi la tua foto alla Hall of Fame.
소셜TypeScript · JavaScriptGitHub @GiacomoM02온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Se ci stai cliccando sai di cosa si tratta. Altrimenti seguici su Ig
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Applicazione web per l'Annuario storico del PN — Università di Pisa. Next.js 14 (App Router + Server Actions), Tailwind CSS, Vercel Postgres (Drizzle ORM), Vercel Blob, Upstash Redis (OTP volatile), Resend (email). • Zero-retention delle email: l'indirizzo istituzionale viene scritto solo su Upstash Redis con TTL di 5 minuti (lib/otp.ts), mai nel database Postgres. Dopo la verifica, il client riceve un token firmato (HMAC, lib/token.ts) che non contiene l'email, valido 15 minuti: è la prova che serve al form per sbloccare l'upload [README 설치·사용 부분 발췌] Setup localeREADME 전문 보기 ↗
Applicazione web per l'Annuario storico del PN — Università di Pisa. Next.js 14 (App Router + Server Actions), Tailwind CSS, Vercel Postgres (Drizzle ORM), Vercel Blob, Upstash Redis (OTP volatile), Resend (email).
annuario-del-pn/
├── drizzle/
│ └── schema.ts # Schema DB: hall_of_fame_entries, archived_editions
├── drizzle.config.ts
├── src/
│ ├── app/
│ │ ├── layout.tsx # Layout root, font, Navbar/Footer
│ │ ├── globals.css
│ │ ├── page.tsx # Home
│ │ ├── archivio/
│ │ │ └── page.tsx # Archivio (griglia edizioni + download PDF)
│ │ └── hall-of-fame/
│ │ ├── page.tsx # Hall of Fame (server component, fetch iniziale)
│ │ └── actions.ts # Server Actions: OTP, verifica, upload, polling
│ ├── components/
│ │ ├── Navbar.tsx
│ │ ├── Footer.tsx
│ │ ├── HallOfFameBoard.tsx # Client: griglia + polling + stato ottimistico
│ │ ├── PhotoCard.tsx
│ │ ├── UploadModal.tsx
│ │ └── UploadForm.tsx # Client: step Email -> OTP -> Dettagli foto
│ └── lib/
│ ├── db.ts # Connessione Drizzle + Vercel Postgres
│ ├── blob-upload.ts # Validazione e upload immagini su Vercel Blob
│ ├── otp.ts # Generazione/verifica OTP su Upstash Redis (TTL)
│ ├── token.ts # Token firmato HMAC "email verificata" (no email dentro)
│ ├── email.ts # Invio OTP via Resend
│ ├── validations.ts # Schemi Zod
│ └── utils.ts
├── tailwind.config.ts
├── next.config.mjs
└── .env.local.example
lib/otp.ts), mai nel
database Postgres. Dopo la verifica, il client riceve un token firmato
(HMAC, lib/token.ts) che non contiene l'email, valido 15 minuti:
è la prova che serve al form per sbloccare l'upload, senza lasciare
traccia persistente dell'identità del mittente.revalidatePath("/hall-of-fame") (rigenera l'SSR per i nuovi visitatori)
e aggiorna otticamente lo stato React lato client di chi ha appena
caricato la foto. Un polling leggero ogni 15s (getLatestEntriesAction)
aggiorna la griglia anche per chi ha già la pagina aperta, senza bisogno
di WebSocket/infrastruttura aggiuntiva (compatibile col piano Vercel free).npm install.env.local.example in .env.local e compila le variabili:
POSTGRES_URL e derivate.BLOB_READ_WRITE_TOKEN.UPSTASH_REDIS_REST_URL / ..._TOKEN.RESEND_API_KEY.OTP_SIGNING_SECRET con openssl rand -base64 32.npm run db:pushnpm run devNon è richiesta un'interfaccia di amministrazione nel primo step: le righe
di archived_editions (PDF + copertina, già caricati su Vercel Blob) si
possono inserire manualmente con npm run db:studio (Drizzle Studio) o via
uno script di seed, finché non verrà costruita una pagina /admin dedicata.
UPSTASH_REDIS_REST_URL/TOKEN, RESEND_API_KEY,
RESEND_FROM_EMAIL, OTP_SIGNING_SECRET, NEXT_PUBLIC_APP_URL./admin protetta per caricare nuove edizioni (PDF + copertina).