尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Flauer's github repo <3
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A personal diary of poems, notes and songs. Every entry belongs to a day; on the calendar,
each day shows one flower per kind it has: pink for poems, gold for notes, lilac for songs.
Apart from the calendar, /videos keeps a list of videos stored on Google Drive or
YouTube. Reading is public; only the diary's owner can write.
Built with Next.js (App Router, Server Components, Server Actions, Cache Components), Neon
Postgres, Drizzle ORM, Zod, jose and Tailwind CSS. The code is in English; the UI is in
Spanish.
| Route | What it does |
|---|---|
/ | Calendar for the current month. ?month=2026-10 shows another. |
/day/YYYY-MM-DD | That day's entries as summaries; each opens its own page, and songs also open on Spotify. |
/entry/[id] | Read a poem, a note or a song (one view, styled by kind). |
/entry/[id]/edit | Edit an entry, or change its kind (session required). |
/write?date=… | New entry (session required). Defaults to today and a poem; &kind=note or &kind=song to start on another kind. |
/videos | Every video as a grid of squares by month, the newest first. In write mode, the form to add one. |
/videos/[id] | Watch a video, with its date, note and the videos before and after it. |
/videos/[id]/edit | Edit a video (session required). |
/login, /logout | Start and end the session. Nothing links to them. |
/poem/[id], the old poem URL, redirects to /entry/[id].
Poems, notes and songs share one entries table; the kind column (poem | note |
song) tells them apart.
title), artist, spotify_url and an
optional "why it fits" (body, up to 1000 characters). The diary can't read the name
or artist from Spotify by itself, so they are typed in.Spotify links are checked and cleaned in src/lib/spotify.ts: open.spotify.com links
(track, album, playlist, episode, show, artist; regional /intl-xx/ paths and the ?si=
share parameter are accepted and dropped), spotify:track:… app URIs and spotify.link
short links from the mobile app. Anything else is rejected. On phones with Spotify
installed, "Abrir en Spotify" opens the app.
Videos aren't uploaded to the diary: they stay on the owner's Google Drive (or on YouTube),
and the videos table keeps where each one is (source: drive | youtube, and
external_id), a title, an optional note, an optional length (duration_seconds, typed
as 1:23 because Drive and YouTube don't tell it to the page), whether it was recorded
upright (vertical, for a 9:16 frame) and date: the day it was added, in
America/Caracas. The server sets that date when the video is saved, and editing never
changes it.
Links are read in src/lib/video-links.ts: Drive files (/file/d/<id>/view, open?id=,
uc?id=) and YouTube videos (watch?v=, youtu.be, /shorts/, /embed/, /live/).
Folders, documents and other sites are rejected. Only the ID is stored, and the page always
embeds Drive's or YouTube's own player built from it (drive.google.com/file/d/<id>/preview,
youtube-nocookie.com/embed/<id>).
Each square in the list shows the video's own still: YouTube's (i.ytimg.com) or Drive's
(drive.google.com/thumbnail, undocumented, and only for files shared publicly). When it
doesn't load, the diary draws its own: a dark square with the flower, the day written by
hand and a play button.
For a Drive video to play for visitors, share it as Anyone with the link. Safari on iPhone can block Drive's player inside other sites (its "Prevent Cross-Site Tracking" setting), so every video page also links to the video on Drive or YouTube itself; if a video doesn't play on an iPhone, uploading it to YouTube as Unlisted works around it.
Text boxes have a fixed height and scroll on their own, so long texts don't stretch the page. On desktop, the day next to the calendar and the side lists while reading or writing fit in the window and scroll inside; the reading sheet does too. On phones the page scrolls as usual.
"Today" is always computed in America/Caracas (TIME_ZONE in src/lib/config.ts). The
app name, subtitle and optional poem signature live in the same file.
| Variable | Purpose |
|---|---|
DATABASE_URL | Neon Postgres connection string. On Vercel the Neon integration sets it. |
OWNER_PASSWORD | Password for /login. You choose it. |
AUTH_SECRET | Random secret that signs the session cookie. At least 32 characters. |
Copy .env.example to .env.local and fill it in. .env.local is git-ignored: never
commit secrets. To generate AUTH_SECRET:
openssl rand -base64 32
Requires Node 22.12+ (see .nvmrc) and pnpm.
pnpm install
cp .env.example .env.local # then fill in the values
pnpm db:migrate # creates the tables
pnpm db:seed # optional: sample poems, notes, songs and videos
pnpm dev
For development, use your own Neon branch rather than the production database (Neon
console: Branches → New branch) and copy its connection string into .env.local. The Neon
integration stores DATABASE_URL in Vercel as a sensitive variable, so vercel env pull
can't download it: copy it from the Neon console instead.
pnpm db:seed is for development only: it refuses to run with NODE_ENV=production, on
Vercel, or against a database that already has entries.
Other scripts:
pnpm lint # ESLint
pnpm format # Prettier
pnpm build # production build
pnpm db:studio # browse the database with Drizzle Studio
The schema lives in src/db/schema.ts and the versioned migrations in drizzle/.
# After changing the schema: generate a new migration and commit it
pnpm db:generate --name describe-the-change
# Apply pending migrations to the database in DATABASE_URL
pnpm db:migrate
db:migrate runs scripts/migrate.ts, which uses Neon's HTTP driver (the same one the app
uses) and prints a clear error when something fails.
On Vercel, vercel.json runs pnpm db:migrate before every production build, so
pending migrations reach the production database on deploy. If a migration fails, the
build fails and the previous deployment stays live. Preview builds skip migrations because
they share the same database.
vercel.json pins the framework to Next.js.DATABASE_URL.OWNER_PASSWORD and AUTH_SECRET for
Production.https://your-domain/login.For every future schema change: pnpm db:generate, commit and push. The next production
deploy migrates the database.