MyGo 云音乐
用 Go 与 MyGo 写成的第三方网易云音乐桌面客户端。原生界面,没有 WebView;边下边播,无损与 Hi-Res,逐字歌词与「律动」,刘海播放器。
Translation pending
Jarvis Creator Studio — studio de distribution de contenu
Translation pending
MediaTypeScript · JavaScriptGitHub @anthosimo33-coderOnlineOwner 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
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Tracker de distribution pour les carrousels TikTok et Instagram de RepackIt. Permet de centraliser, suivre et orchestrer la diffusion de contenus carrousel sur les deux plateformes.
next@latest (équivalent fonctionnel à Next.js 15 demandé : App Router, Server Components, Server Actions)@tailwindcss/postcss)base-novabutton, input, select, dropdown-menu, dialog, table, card, badge, tabs, label, textarea, sonner (remplace toast, déprécié dans le registry shadcn), calendar, popover.
Ce projet est l'outil interne de RepackIt pour suivre la distribution des carrousels (TikTok + Instagram) : programmation, statut de publication, métriques par plateforme, et reporting cross-canal.
pnpm dev # Lance le dev server sur http://localhost:3000
pnpm build # Build production
pnpm start # Lance le build en mode production
pnpm lint # Lint le code (ESLint + config Next.js)
app/ # App Router (pages, layouts, route handlers)
components/ui/ # Composants shadcn/ui
lib/ # Utilitaires (cn, etc.)
public/ # Assets statiques
Le build Vercel pousse le backend Convex dans le même build que le front :
vercel.json (commité) appelle npx convex deploy --cmd 'pnpm build && …'.
convex deploy lance d'abord --cmd (le next build), puis pousse Convex,
et seulement si --cmd a réussi.
Garde de tête (scripts/convex-head-guard.mjs) : deux merges rapprochés
lancent deux builds Production en parallèle, et le dernier à pousser Convex
gagne, même s'il porte le commit le plus ancien (vu le 2026-10-29). Le garde
tourne avant le build, puis en dernière commande du --cmd, juste avant le
push. Un build de production dont le commit n'est plus la tête de main échoue
sans pousser ; le build de la tête s'en charge. Une tête illisible
(git ls-remote anonyme : le dépôt doit rester public) fait aussi échouer le
build.
Configuration une seule fois :
repackit-distribution-tracker → deployment prod
fiery-wolf-460 → Settings → Generate Production Deploy Key.CONVEX_DEPLOY_KEY (scope Production) avec la clé générée.Sans CONVEX_DEPLOY_KEY, le build Vercel échoue — c'est voulu : on ne peut
plus shipper du code sans son schéma.
Toutes les tables métier sont scopées par projectId (tables projects +
memberships). Numérotation C###/S###/SR### par projet.
À cause du déploiement atomique (le convex deploy du build pousse le schéma
AVANT toute migration data), le rollout a été fait en 2 phases (prod
backfillée le 2026-06-12) :
Phase 1 (feat(multi-tenant)) — projectId en v.optional + tables
projects/memberships + indexes. Après déploiement, lancé une fois
sur prod :
./node_modules/.bin/convex run migrations:setupRepackitProject --prod
→ projet repackit, membership admin du superadmin, backfill projectId
partout, unset vuesJ1/J3/J7 (TD-016). Comptages des 9 tables inchangés
(64 publications, 490 hooks, etc.), KPIs dashboard identiques.
Phase 2 (chore(multi-tenant)) — la prod étant backfillée, projectId
resserré en v.id("projects") (non-optional) sur les 9 tables et
vuesJ1/J3/J7 retirés du schéma. Le succès du convex deploy au build
prouve qu'aucun doc prod ne viole le schéma resserré.
TD-017 (comptes.actif) reste différé : lib/compte-status.ts + ~12 specs e2e
le lisent encore.
Pour amorcer un nouveau deployment (dev/test/prod neuf), lancer
setupRepackitProject après le 1er provisioning auth (crée le projet repackit
/admin/[projectSlug] + switcher + création de projetL'app interne vit sous /admin/[projectSlug]/… (dashboard, comptes, carrousels,
shorts, screenrecorder, biblio-hooks, inspirations). L'URL est la source de
vérité du projet actif : ProjectProvider lit le segment [projectSlug] et
le résout via api.projects.getProjectForCurrentUser (vérif superadmin ou
membership ; 404 propre si slug inexistant, accès refusé sinon). Plus aucun
projet implicite ni stocké en localStorage.
/ résout le projet par défaut de l'utilisateur (getCurrentProject) puis
redirige vers /admin/<slug>/dashboard. Les anciennes routes (/dashboard,
/carrousels?carouselId=…, /nouveau, /tracker…) redirigent vers
/admin/repackit/… (slug par défaut). /p/[carouselId] est un resolver
cross-projet : il cherche le carouselId dans les projets accessibles puis
redirige vers la route scopée (404 sinon).api.projects.listMyProjects :
superadmin → tous, sinon memberships). « Créer un projet » (superadmin,
api.projects.createProject) : modal nom + slug + couleur d'accent (#FF5200)
api.projects.getMe) + déconnexion.tracker.snapshot-age:<slug> (période J+X par projet) ;
sidebar-collapsed et le schéma des filterPresets restent globaux./admin/e2e-test/… (helper adminPath) sur un projet
dédié e2e-test (créé par auth.setup.ts).Reste différé (hors P3) : rôle creator + portail /app, theming par
accentColor.
L'app est protégée de bout en bout :
convex/functions.ts. C'est LA barrière de sécurité —
NEXT_PUBLIC_CONVEX_URL est publique dans le bundle, protéger les pages ne
suffit pas. Couches (de la plus large à la plus stricte) :
authedQuery / authedMutation : session requise (ctx.userId) ;superadminMutation : rôle global superadmin ;projectQuery / projectMutation : accès au projet (membership ou
superadmin), tout rôle — ctx.projectId injecté ;adminQuery / adminMutation : membership admin (ou superadmin) sur le
projet. Toute l'app interne passe dessus → le rôle creator n'y a
aucun accès ;creatorQuery / creatorMutation : membership creator, résout SA fiche
creators et injecte ctx.creatorId ; la donnée servie est filtrée par
ce creatorId (portail /app) ;publicQuery : pré-session, réservé à l'aperçu d'invitation (/join).proxy.ts (middleware Next 16) redirige tout visiteur
sans session vers /login (sauf routes publiques /login et /join/...).
Routage par rôle : un creator sur /admin/* est renvoyé vers /app, un
admin/superadmin sur /app vers son /admin.users vide → rôle
superadmin). Ensuite, création de comptes uniquement par invitation :
un admin invite un créateur (/admin/[slug]/createurs) → lien /join/<token>
(uuid, +14 j, usage unique). Le signUp n'est autorisé que par un token
valide (convex/auth.ts createOrUpdateUser) : il crée le user (rôle
member), le membership creator, lie la fiche et marque l'invitation
consommée — le tout atomiquement. Token absent/expiré/réutilisé → rejet sans
leak.# 1. Clés JWT (affiche les deux commandes `convex env set` à exécuter)
pnpm tsx scripts/generate-jwt-keys.ts
# 2. URL du site (redirections auth)
./node_modules/.bin/convex env set SITE_URL http://localhost:3000 # prod : URL Vercel, avec --prod
# 3. Secret e2e — deployments de DEV/TEST UNIQUEMENT, JAMAIS en prod
./node_modules/.bin/convex env set E2E_SECRET <valeur ≥ 8 caractères>
# 3 bis. JWT longue durée — DEV/TEST UNIQUEMENT, JAMAIS en prod (prod = 1h).
# Défense en profondeur du fixture d'auth e2e : évite tout refresh de token
# pendant un test (les refresh tokens sont single-use → races sinon). 30 jours.
./node_modules/.bin/convex env set JWT_DURATION_MS 2592000000
# 4. Pousser schéma + fonctions, puis créer le compte initial sur /login
./node_modules/.bin/convex dev --once # prod : convex deploy (ou push Vercel)
Premier compte : ouvrir /login → « Créer le compte initial » → superadmin.
Compte perdu ou E2E_SECRET changé après création du user e2e :
./node_modules/.bin/convex run maintenance:wipeAuthTables rouvre la fenêtre
bootstrap (purge users + sessions).
Ces deux-là coûtent une heure chacun si on ne les connaît pas.
1. JWKS s'écrit en JSON BRUT, jamais requoté. Une valeur double-encodée
(JWKS="{\"keys\":…}" au lieu de JWKS={"keys":…}) fait servir au déploiement
un document de découverte invalide, et le backend répond :
AuthProviderDiscoveryFailed: Auth provider discovery of http://… failed
Error discovering auth provider: …, Failed to parse server response
Le message accuse la découverte réseau alors que la cause est l'encodage : les endpoints répondent bien 200, c'est leur contenu qui n'est pas du JSON.
2. Ne passe JAMAIS la clé privée en ARGUMENT.
convex env set JWT_PRIVATE_KEY -- "-----BEGIN PRIVATE KEY----- …" : le CLI
interprète -----BEGIN comme une option, échoue avec
error: unknown option '-----BEGIN PRIVATE KEY----- …' — et écho la clé
privée en clair dans ce message. Toujours passer par un fichier :
convex env set --from-file <fichier.env> # valeurs jamais en argv
Le user e2e ([email protected], mot de passe = E2E_SECRET) est créé au
premier run par e2e/auth.setup.ts via la fenêtre bootstrap ; sa session
(storageState) est partagée par toutes les specs.
Backend LOCAL (chemin par défaut, local ET CI) — la suite e2e ne dépend plus d'un déploiement cloud :
./scripts/convex-local.sh start # backend + schéma + auth (~4 s)
eval "$(./scripts/convex-local.sh env)" && pnpm test:e2e
./scripts/convex-local.sh reset # base VIERGE (état résiduel)
./scripts/convex-local.sh stop
Backend Convex open-source, SQLite, base neuve par run. Le tag du binaire
est épinglé dans le script (upstream ne publie aucune matrice de
compatibilité CLI ↔ backend, et l'image Docker n'existe qu'en :latest) : le
monter est une décision délibérée, à valider en relançant la suite entière.
Tout l'état vit dans .convex-local/ (gitignoré) ; .env.local n'est jamais
touché, les variables self-hosted passent par --env-file. Mélanger cloud et
self-hosted dans un même fichier est refusé par Convex.
En CI : aucun secret GitHub n'est nécessaire (secret d'instance, clé admin,
clés JWT et E2E_SECRET sont générés par run). Deux PR peuvent tester en
parallèle : chacune a son backend.
Contre le cloud (dépannage ponctuel) : exporter NEXT_PUBLIC_CONVEX_URL +
E2E_SECRET vers le deployment visé, qui doit être provisionné avec les
fonctions à jour. À réserver au diagnostic d'une divergence backend.
Re-seed des hooks en prod (exceptionnel) : définir temporairement
E2E_SECRET sur la prod via convex env set --prod, lancer
pnpm tsx scripts/run-seed.ts --env prod, puis retirer la variable.
Smoke prod (scripts/smoke-prod-presets.ts) : s'authentifie avec un vrai
compte prod via PROD_SMOKE_EMAIL / PROD_SMOKE_PASSWORD
(.env.prod.local).
seedHooksclearHookscleanupTest*wipeAllPublicationssecretE2E_SECRET