iArt.ai
AI 모션 그래픽 소프트웨어, 누구나 사용할 수 있는 After Effects 대안, 텍스트 프롬프트로 몇 분 안에 애니메이션·설명 영상 제작
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기A watch tracker you keep with the people you watch with: a personal list, a shared list for two, and a live library of what to watch. React, Supabase, TMDB.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A watch tracker you keep with the people you watch with. Every film and series you have seen or mean to, with your own rating and notes, plus a second list you share with a friend (or a few) where everyone adds titles and rates them. Real posters, cast, and runtimes come from TMDB; accounts and data live on Supabase.
Web first (React), with the backend kept as a plain API so a native iOS client can reuse it later. Every user's data is isolated at the database level, so this runs as a real multi-user app, not a single-owner tool.
Built by Anwar Creative Studio.README 전문 보기 ↗A watch tracker you keep with the people you watch with. Every film and series you have seen or mean to, with your own rating and notes, plus a second list you share with a friend (or a few) where everyone adds titles and rates them. Real posters, cast, and runtimes come from TMDB; accounts and data live on Supabase.
Web first (React), with the backend kept as a plain API so a native iOS client can reuse it later. Every user's data is isolated at the database level, so this runs as a real multi-user app, not a single-owner tool.
Built by Anwar Creative Studio.
A list entry has an owner_type of either user or space. A personal list and a shared list run through the same code, they just point at a different owner. Ratings are their own table, one row per person per entry, which is why a shared entry can hold two ratings at once.
Titles are cached in a local titles table when first added, so a list points at a stable row and your history does not shift if TMDB changes.
Postgres row level security does the access control. A signed-in user can read and write their own user entries and any space entry for a space they belong to. Ratings are readable by anyone who can see the parent entry and writable only for your own row. Neither list_entries nor ratings nor the RLS policies that gate them cap a space's membership; the two security definer functions that grow one do that instead. Starting a space (create_couple_space) and adding another member to an existing one (add_space_member) both first check the friendship being relied on is accepted — and specifically the acting user's own friendship with whoever is being added, not any existing member's.
/api/* Vercel Edge functions proxy TMDB, OMDb and The Guardian: the keys stay server-side and responses are cached on the CDN, so the free-tier limits are shared across everyone rather than spent per visitThe browser never talks to TMDB, OMDb or The Guardian directly. It calls
/api/tmdb, /api/omdb and /api/guardian, which:
VITE_ prefix, never bundled),Cache-Control: s-maxage so Vercel's edge caches the response — title
detail for a day, discovery feeds for 15 minutes, the press feed for 30,
IMDb/RT scores for a week,So the first person to open "trending" this hour pays the upstream calls; the
next few thousand are served from the edge. During vite dev a small plugin
in vite.config.ts runs the same handler modules so /api/* works locally.
Each function also runs a best-effort per-IP rate limit (in the edge instance's memory, ceilings well above any real session) so one client cannot run the free-tier budgets down. For a hard limit, add a rule in the Vercel firewall.
/api/poster is opt-in (see the env table). When it and VITE_POSTER_CACHE
are set, it copies each TMDB poster into a public Supabase Storage bucket the
first time a card renders it, and the grid serves the Storage copy from then
on. Without it, cards use TMDB image URLs as before.
Letterboxd is a public diary. A group text is where "what should we watch" goes to die. Stub is the small private middle: one list that is yours, one that is ours, and a real catalogue to pull from, with no feed and no account required from anyone you are not already watching with.
npm install
supabase/migrations/ in order (0001 through 0008), or supabase link and supabase db push.anon public key.eyJ).cp .env.example .env
# then fill in the values
| var | side | required | what |
|---|---|---|---|
VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY | client | yes | the database and auth |
TMDB_ACCESS_TOKEN | server (/api/*) | yes | titles, artwork, discovery |
OMDB_API_KEY | server | no | IMDb / Rotten Tomatoes / Metacritic scores |
GUARDIAN_API_KEY | server | no | the "In the press" feed |
SUPABASE_SERVICE_ROLE_KEY | server | no | lets /api/poster write to Storage |
VITE_POSTER_CACHE | client | no | set to 1 to serve posters from Storage |
VITE_SENTRY_DSN | client | no | a Sentry DSN turns on crash reporting |
The server vars have no VITE_ prefix on purpose, so they never reach the
browser. On Vercel, add them as plain (not VITE_) environment variables;
vite dev reads them from .env for the local /api plugin. For the poster
cache, also run supabase/migrations/0005_posters_bucket.sql and set
VITE_POSTER_CACHE=1.
npm run dev
Open the local URL Vite prints, create an account, and start adding titles from the Library. Until the two Supabase values are set, the app shows a setup screen instead of booting.
| Table | Purpose |
|---|---|
profiles | One row per auth user, created by a trigger on sign up. Holds the username and display name. |
titles | Local cache of TMDB media so lists reference a stable row. |
list_entries | A title on a list. owner_type is user or space; carries status, note, and watched date. |
ratings | One row per person per entry. This is how everyone's ratings on a shared entry sit side by side. |
friendships | Requester, addressee, and status (pending or accepted). |
spaces + space_members | A shared list and who belongs to it. create_couple_space(friend) starts one between two accepted friends; add_space_member(space, friend) grows an existing one, up to 8 people, gated on the adder's own friendship with whoever they're adding. |
notifications | One row per (recipient, entry, kind). Triggers on ratings and list_entries.note write these for the other space member; a repeat rating or note edit refreshes the row instead of adding another. Delivered live over Supabase realtime. |
npm run dev # dev server
npm run build # typecheck, then production build
npm run typecheck # types only
npm test # unit tests (Vitest)
npm run test:db # row-level-security tests (needs a local Supabase: supabase start)
npm run preview # serve the build
npm run icons # regenerate the PNG icons from the mark
npm test covers the pure logic: OMDb score parsing, Guardian article mapping, TMDB normalisation and the upcoming/classic filters, list averages, and theme persistence.
supabase/tests/rls_test.sql is a pgTAP suite that runs against a throwaway database (supabase start && npm run test:db, or the CI database job). It asserts that one user cannot read or write another's personal list or ratings or profile, that a shared space is visible only to its members, that a space can grow past a pair but only when the acting member has their own accepted friendship with whoever they're adding (not merely riding on a fellow member's), that friend_activity and list_compare only return data between accepted friends, and that delete_own_account removes exactly the caller and their personal rows.
CI (.github/workflows/ci.yml) runs typecheck, unit tests and the build on every push, plus the database tests on a fresh Supabase stack.
/api/* proxy that keeps the third-party keys server-side and caches their responses on the CDN./api/poster caches TMDB poster art into Supabase Storage so the grid does not depend on TMDB's CDN. Off until SUPABASE_SERVICE_ROLE_KEY and VITE_POSTER_CACHE are set./api/* function, and crash reporting to Sentry when VITE_SENTRY_DSN is set.prototype/archive.html is the original single file version that seeded the idea: one HTML file, no accounts, list kept in the page itself.