@mostajs/marketplace
v0.1.0
Published
Cœur métier MINCE de place de marché interne + appels à prestations : besoin ↔ propositions/devis, cycle RFP 8 étapes → facturation, messagerie, matching. COMPOSE numbering/payment/notifications/ro-pla. Assemble P1 Hadhinat.
Maintainers
Readme
@mostajs/marketplace
Auteur : Dr Hamid MADANI [email protected] Licence : AGPL-3.0-or-later
Cœur métier mince de place de marché interne + appels à prestations : une entreprise publie un besoin, les autres soumettent devis + délai, échangent par messagerie, et le besoin parcourt un cycle RFP en 8 étapes jusqu'à la facturation. Il compose les briques @mostajs/* sans rien réimplémenter (motif « domaine mince » de @mostajs/crm). Couvre les besoins F7 + F8 du projet P1 Hadhinat MostaJS Technopark.
Vocabulaire
RFP (Request For Proposal) = appel à propositions / appel à prestations : un demandeur publie un besoin, des prestataires répondent par une offre (devis + délai), le demandeur sélectionne la meilleure.
Cycle « 8 étapes » = le cycle de vie imposé par la spec (Module 8), modélisé par les statuts de la demande :
| # | Étape |
status| |---|---|---| | 1 | Dépôt de la demande |submitted| | 2 | Validation par la couveuse |validated| | 3 | Publication |published| | 4 | Réception des offres | (restepublished) | | 5 | Sélection |selected| | 6 | Réalisation |in_progress| | 7 | Validation du livrable |delivered| | 8 | Facturation |invoiced→closed|Matching = mise en correspondance « besoin ↔ meilleure proposition » (évolution E2).
matching.rank()classe les devis (défaut : heuristique prix + délai ; en prod, on injecte@mostajs/ro-plaviamatcher).
Installation
npm i @mostajs/marketplaceExemple minimal
import { createMarketplace, createMemoryRepositories } from '@mostajs/marketplace';
const mp = createMarketplace({
repositories: createMemoryRepositories(),
numbering: { next: (k) => (k === 'request' ? 'DEM-2026-001' : 'DEV-2026-001') },
payment: { charge: async ({ amount }) => ({ ref: 'PAY-1', amount }) }, // facturation (étape 8)
});
// Étapes 1-3 : une entreprise dépose un besoin, la couveuse valide puis publie
const r = await mp.requests.create('greenagro', { title: 'Site e-commerce', budget: 120000 });
await mp.requests.validate(r.id);
await mp.requests.publish(r.id);
// Étape 4 : des prestataires soumettent des devis
const p1 = await mp.proposals.submit(r.id, { providerCompanyId: 'startupdz', amount: 95000, leadTimeDays: 30 });
const p2 = await mp.proposals.submit(r.id, { providerCompanyId: 'mediaplus', amount: 78000, leadTimeDays: 20 });
// Étape 5 : matching + sélection du mieux classé
const [best] = await mp.matching.rank(r.id); // p2 (moins cher, plus rapide)
await mp.requests.select(r.id, best.proposalId);
// Étapes 6-8 : réalisation → validation → facturation
await mp.requests.start(r.id);
await mp.requests.deliver(r.id);
await mp.requests.invoice(r.id, { method: 'cib' }); // compose @mostajs/paymentRéférence API
| Domaine | Méthodes |
|---|---|
| requests | create(1) · validate(2) · publish(3) · select(5) · start(6) · deliver(7) · invoice(8) · close · get/list/byCompany/listPublished |
| proposals | submit(4) · list · get · withdraw |
| messages | post · list |
| matching | rank(requestId) |
| pilotage | dashboard · reportingSource |
Composition
marketplace compose (injection) : @mostajs/numbering (n° demande/devis), @mostajs/payment (facturation), @mostajs/notifications, @mostajs/ro-pla (matching avancé via matcher), @mostajs/incubator (entreprises). Hors périmètre (composés par l'app) : chat-stack (messagerie complète), workflow-stack, encaissement réel payment, ged. Tout est optionnel sauf repositories.requests.
Tests & exemple
npm test # 6 tests unitaires
npm run example # appel à prestations entre 2 entreprises incubées (compose incubator/users/numbering/payment/reporting)