Saleor Store
우리 컬렉션을 쇼핑하세요
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Toomny — marketplace de talents pour l Afrique de l Ouest. Paiement mobile money, sequestre, bilingue FR/EN.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Marketplace de talents pour l'Afrique de l'Ouest. Les PME recrutent des prestataires du continent, paient en mobile money, et les fonds restent sécurisés jusqu'à la livraison. Domaine : toomny.com · Statut : structure posée, produit en attente de la Phase 0.README 전문 보기 ↗
Marketplace de talents pour l'Afrique de l'Ouest. Les PME recrutent des prestataires du continent, paient en mobile money, et les fonds restent sécurisés jusqu'à la livraison.
Domaine : toomny.com · Statut : produit fonctionnel en français, anglais prêt sur les parcours connectés.
Le parcours complet tourne : catalogue public avec forfaits et avis, commande, paiement mobile money via GeniusPay (encaissement), séquestre miroir, messagerie temps réel, litiges avec arbitrage admin, KYC avec recours humain, profils prestataires, versements en file manuelle, et back-office (commandes, litiges, KYC, utilisateurs, prestations, catégories).
Ce qui est posé depuis le premier commit et ne change pas : le modèle monétaire (entiers, multi-devises), la machine à états du séquestre, le journal comptable en ajout seul, et l'i18n FR/EN sans chaîne en dur.
Elles sortent directement de l'étude de marché et ne sont pas négociables.
En zone UEMOA, la détention de fonds du public est réservée aux banques, établissements financiers de paiement, SFD autorisés et établissements de monnaie électronique agréés par la BCEAO. Les agrégateurs de paiement n'ont pas de cadre propre et sont traités comme prestataires techniques.
Conséquence : le séquestre est porté par un partenaire agréé. escrow_holds n'est qu'un miroir local de l'état côté partenaire, et aucune colonne du schéma ne représente un solde détenu par Toomny. Voir src/lib/payments/types.ts.
Tout montant est un entier dans la plus petite unité de la devise, jamais un flottant. Le XOF n'a pas de subdivision — exponent 0 — contrairement à l'USD. L'interface n'expose que le XOF en phase 1 ; la base est déjà prête pour le cedi, le naira et le dollar. Voir src/lib/money.ts.
ledger_entries n'est jamais modifié ni supprimé (trigger en base, y compris pour la clé service) ; une correction se fait par une écriture inverse. Ce journal conditionne l'attestation de revenus et l'avance sur mission, les deux produits financiers qui porteront la marge réelle. Voir src/lib/order-ledger.ts.
| Paramètre | Valeur | Où |
|---|---|---|
| Commission prestataire | 10 % (1000 bps) | DEFAULT_COMMISSION_BPS |
| Commission client | 0 % | — |
| Délai de versement annoncé | 24 h | PAYOUT_SLA_HOURS |
| Validation automatique après livraison | 72 h | AUTO_RELEASE_AFTER_DELIVERY_HOURS (tâche quotidienne 06:00 UTC, délai effectif 72–96 h) |
L'arrondi de la commission se fait toujours au détriment de la plateforme, jamais du prestataire.
Next.js 16 · React 19 · Tailwind 4 · TypeScript · Supabase (PostgreSQL + Auth + Storage + Realtime) · Drizzle (DDL uniquement) · Vercel.
npm install
cp .env.example .env.local # puis remplir
npm run db:push # crée les tables depuis src/db/schema.ts
# puis, dans l'éditeur SQL Supabase (projet de test d'abord), jouer DANS L'ORDRE :
# supabase/migrations/0001_security_rls.sql # RLS, journal immuable, bucket KYC
# supabase/migrations/0002_…_0010_… # stats admin, trigger, rate limits, audit, realtime…
# supabase/migrations/0011_…_0020_… # couvertures, galerie, tags, forfaits, inquiries, réparations
npm run dev
⚠️ Sans les migrations, la base n'a aucune politique d'accès : la clé anonyme publique donnerait accès à toutes les tables. Chaque fichier est rejouable sans risque (
if not exists,drop … if exists).
| Commande | Rôle |
|---|---|
npm run dev | serveur de développement |
npm run build | build de production |
npm run lint | ESLint |
npm run typecheck | TypeScript sans émission |
npm run test | Vitest (logique métier, i18n, sécurité) |
npm run db:push | pousse le schéma Drizzle vers la base (DDL uniquement) |
npm run db:generate | génère les migrations Drizzle |
L'accès aux données passe par le client Supabase (@/lib/supabase/server en session, @/lib/supabase/admin côté serveur après contrôle explicite) ; Drizzle ne sert qu'à créer le schéma, jamais à requêter.
src/
├── app/
│ ├── (fr)/ parcours français : landing, catalogue, commandes,
│ │ messages, litiges, dashboard, back-office /admin
│ ├── (en)/en version anglaise : accueil, auth, CGU
│ └── api/ auth, paiements, webhooks GeniusPay, uploads, export RGPD, cron 72 h
├── components/ landing, catalogue, commandes, dashboard, admin, auth
│ └── dashboard/pro.tsx kit premium des espaces connectés (pastilles, stats,
│ sections, tableaux, bandeaux) — client-safe, sans requête
├── content/ contenus éditoriaux (landing, CGU)
├── db/schema.ts schéma Drizzle, source du DDL (jamais requêté)
├── i18n/ dictionnaires FR/EN par domaine
├── lib/
│ ├── money.ts arithmétique monétaire en entiers
│ ├── escrow.ts machine à états de la commande
│ ├── order-ledger.ts écritures du journal + compteurs prestataire
│ ├── packages.ts validation des forfaits
│ ├── payments/ contrat PaymentProvider + GeniusPay
│ └── supabase/ clients session, navigateur et service
└── proxy.ts CSP + langue + rafraîchissement de session
supabase/migrations/ RLS, fonctions SQL, buckets, seeds de démo
Les tableaux de bord, le back-office et les parcours de commande partagent un même vocabulaire visuel, défini à deux endroits seulement :
src/app/globals.css — les briques : .btn-primary / .btn-gold / .btn-secondary / .btn-ghost / .btn-danger / .btn-success / .btn-warn
(+ .btn-sm), .card et .card-pad, .chip et .chip-active, .notice et
ses quatre tons, .input, le bandeau .hero-band. Les couleurs passent par
des tokens (--tone-*, --action-*, rampes --color-brand-* et
--color-gold-*) : aucun bg-red-500 en dur, le mode sombre suit tout seul.src/components/dashboard/pro.tsx — les composants : Pill et ses fonctions
de ton (orderTone, serviceTone, payoutTone, disputeTone, kycTone,
roleTone), ProStat, MiniStat, Section, TableCard, FilterTabs,
Notice, QuickAction, Avatar, ProgressBar./charte affiche toutes ces briques sur une seule page, sans base de données
(la route n'existe pas en production) : c'est l'écran de contrôle avant
d'habiller une nouvelle page, mode clair comme sombre.
queued, pilotées dans /admin/payouts (prise en charge → paiement mobile money hors app → marquage payé/échec, avec écritures payout/refund au journal). Reste : le payout automatique quand un partenaire l'exposera./demandes (conversations par prestation, accusés de lecture), avec notification in-app à chaque message. Reste : notifier hors app (e-mail ou push) — aucun canal externe pour l'instant./en* = points d'entrée anglais garantis, lang/hreflang dynamiques, sitemap + robots). Le login et le sélecteur du header synchronisent preferred_locale dans les deux sens. Choix assumé : pas de miroirs /en/* pour les pages internes (coût SEO/maintenance) — réévaluer à l'expansion anglophone.