mirror of
https://github.com/arthur-pbty/flint.git
synced 2026-08-01 20:29:03 +02:00
Add documentation & netoyage de fichier
This commit is contained in:
+32
-9
@@ -1,18 +1,41 @@
|
|||||||
node_modules
|
# =========================
|
||||||
build
|
# Dependencies
|
||||||
dist
|
# =========================
|
||||||
.next
|
node_modules/
|
||||||
apps/*/dist
|
|
||||||
apps/*/.next
|
# =========================
|
||||||
packages/*/dist
|
# Builds
|
||||||
|
# =========================
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
.next/
|
||||||
|
apps/*/dist/
|
||||||
|
apps/*/.next/
|
||||||
|
packages/*/dist/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# TypeScript
|
||||||
|
# =========================
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
**/*.tsbuildinfo
|
**/*.tsbuildinfo
|
||||||
.git
|
|
||||||
.gitignore
|
# =========================
|
||||||
|
# Environment variables
|
||||||
|
# =========================
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Logs
|
||||||
|
# =========================
|
||||||
*.log
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Git
|
||||||
|
# =========================
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
@@ -3,7 +3,6 @@ NODE_ENV=production
|
|||||||
# PORT PUBLIC
|
# PORT PUBLIC
|
||||||
WEB_PORT=3000
|
WEB_PORT=3000
|
||||||
API_PORT=4000
|
API_PORT=4000
|
||||||
BOT_PORT=4100
|
|
||||||
|
|
||||||
# DB
|
# DB
|
||||||
POSTGRES_DB=
|
POSTGRES_DB=
|
||||||
|
|||||||
+32
-1
@@ -1,16 +1,47 @@
|
|||||||
|
# =========================
|
||||||
|
# Dependencies
|
||||||
|
# =========================
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Build outputs
|
||||||
|
# =========================
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
.next/
|
.next/
|
||||||
|
|
||||||
apps/*/dist/
|
apps/*/dist/
|
||||||
apps/*/.next/
|
apps/*/.next/
|
||||||
packages/*/dist/
|
packages/*/dist/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# TypeScript
|
||||||
|
# =========================
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Environment variables
|
||||||
|
# =========================
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
.vscode/
|
|
||||||
|
# =========================
|
||||||
|
# Logs
|
||||||
|
# =========================
|
||||||
*.log
|
*.log
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
pnpm-debug.log*
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Editor / IDE
|
||||||
|
# =========================
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# OS files
|
||||||
|
# =========================
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Copyright (c) 2026 Arthur
|
||||||
|
|
||||||
|
Licence pour tous les projets Arthur
|
||||||
|
|
||||||
|
1. Définition
|
||||||
|
Cette licence définit les droits et obligations concernant l'utilisation, la modification et la redistribution du code fourni par l'auteur.
|
||||||
|
|
||||||
|
2. Autorisation d'utilisation
|
||||||
|
Vous êtes libre d'utiliser ce code pour vos projets personnels ou commerciaux. L'utilisation doit inclure une mention de l'auteur d’une manière libre (ex: "inspiré de ArthurP").
|
||||||
|
|
||||||
|
3. Modification
|
||||||
|
Vous pouvez modifier, adapter ou améliorer le code pour vos besoins. Les modifications doivent être identifiées comme telles et ne doivent pas être présentées comme l'original.
|
||||||
|
|
||||||
|
4. Redistribution
|
||||||
|
- Le code original **ne peut pas être redistribué tel quel**.
|
||||||
|
- Les versions modifiées peuvent être partagées, sous réserve de mentionner l'auteur original.
|
||||||
|
|
||||||
|
5. Usage commercial
|
||||||
|
L’usage commercial des versions modifiées est autorisé. Vous pouvez générer des revenus avec votre version modifiée.
|
||||||
|
|
||||||
|
6. Attribution
|
||||||
|
L'auteur original doit être cité d’une manière libre, mais visible, sur tout projet utilisant ce code ou ses dérivés.
|
||||||
|
|
||||||
|
7. Responsabilité
|
||||||
|
Le code est fourni "tel quel", sans garantie d’aucune sorte. L’auteur décline toute responsabilité pour tout dommage direct ou indirect résultant de l’utilisation du code.
|
||||||
@@ -1,173 +1,252 @@
|
|||||||
# Discord Bot SaaS Platform (Multi-Tenant)
|
# 🚀 Flint — Discord Bot SaaS Platform (Multi-Tenant)
|
||||||
|
|
||||||
Plateforme SaaS multi-tenant pour gérer des bots Discord avec un seul service bot dynamique.
|
# [https://flint.arthurp.fr](https://flint.arthurp.fr/)
|
||||||
|
|
||||||
## Vue d'ensemble
|
Flint est une plateforme SaaS permettant de gérer et orchestrer plusieurs bots Discord depuis une seule infrastructure scalable.
|
||||||
|
|
||||||
Cette version transforme le modèle "1 conteneur = 1 bot" en architecture scalable:
|
Elle repose sur une architecture **multi-tenant**, sécurisée et conçue pour supporter une montée en charge horizontale.
|
||||||
|
|
||||||
- Un seul `apps/bot` qui gère `N` bots dynamiquement
|
---
|
||||||
- `apps/api` pour OAuth2 Discord + API sécurisée + orchestration des bots
|
|
||||||
- `apps/web` (Next.js) pour le dashboard
|
|
||||||
- PostgreSQL pour les données tenant-scopées
|
|
||||||
- Redis + BullMQ pour la file d'actions de contrôle (`start`, `stop`, `restart`)
|
|
||||||
|
|
||||||
## Structure Monorepo
|
## 🧠 Concept
|
||||||
|
|
||||||
```text
|
Au lieu de :
|
||||||
|
|
||||||
|
> ❌ 1 bot = 1 container
|
||||||
|
|
||||||
|
Flint utilise :
|
||||||
|
|
||||||
|
> ✅ 1 bot manager = N bots dynamiques
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Architecture globale
|
||||||
|
|
||||||
|
```txt
|
||||||
/apps
|
/apps
|
||||||
/web # Next.js dashboard
|
web → Dashboard Next.js (UI SaaS)
|
||||||
/api # Backend API (OAuth2, JWT, gestion bots)
|
api → Backend (OAuth2 Discord + JWT + API multi-tenant)
|
||||||
/bot # Bot manager multi-instance dynamique
|
bot → Bot manager (runtime multi-bots Discord)
|
||||||
/packages
|
/packages
|
||||||
/shared # Types, crypto token, helpers Redis namespacés
|
shared → Types, crypto, Redis helpers
|
||||||
/database
|
/database
|
||||||
/migrations # SQL versionné (inclut multi-tenant SaaS)
|
migrations → Schéma PostgreSQL versionné
|
||||||
docker-compose.yml
|
|
||||||
.env
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Architecture Runtime
|
---
|
||||||
|
|
||||||
### 1) API (`apps/api`)
|
## ⚙️ Stack technique
|
||||||
|
|
||||||
- OAuth2 Discord (`/auth/discord/login`, `/auth/discord/callback`)
|
* **Frontend** : Next.js (App Router) + TailwindCSS
|
||||||
- Session JWT en cookie `httpOnly`
|
* **Backend** : Node.js + Express
|
||||||
- Endpoints multi-tenant pour bots (`/api/bots`)
|
* **Bot runtime** : Discord.js multi-instances
|
||||||
- Validation du token bot via l'API Discord avant stockage
|
* **DB** : PostgreSQL 16
|
||||||
- Chiffrement AES-256-GCM des tokens en base
|
* **Queue** : Redis + BullMQ
|
||||||
- Publication des actions de contrôle via BullMQ (Redis)
|
* **Infra** : Docker Compose
|
||||||
- Rate limit par tenant (clé Redis namespacée `tenant:{tenantId}:...`)
|
|
||||||
|
|
||||||
### 2) Bot Manager (`apps/bot`)
|
---
|
||||||
|
|
||||||
- Charge les bots à relancer depuis PostgreSQL au démarrage
|
## 🤖 Architecture runtime
|
||||||
- Maintient une map en mémoire:
|
|
||||||
|
### API (`apps/api`)
|
||||||
|
|
||||||
|
* OAuth2 Discord login
|
||||||
|
* JWT httpOnly session
|
||||||
|
* API multi-tenant complète
|
||||||
|
* Gestion des bots :
|
||||||
|
|
||||||
|
* create / start / stop / restart
|
||||||
|
* Chiffrement AES-256-GCM des tokens Discord
|
||||||
|
* Rate limiting par tenant
|
||||||
|
* Queue de contrôle via BullMQ
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Bot Manager (`apps/bot`)
|
||||||
|
|
||||||
|
* Un seul service pour tous les bots
|
||||||
|
* Gestion dynamique :
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
Map<botId, DiscordClient>;
|
Map<botId, DiscordClient>
|
||||||
```
|
```
|
||||||
|
|
||||||
- Worker BullMQ: consomme les jobs `start|stop|restart`
|
* Worker Redis (BullMQ) :
|
||||||
- Met à jour l'état runtime (`starting`, `running`, `stopping`, `error`)
|
|
||||||
- Journalise les événements runtime en base (`bot_runtime_events`)
|
|
||||||
|
|
||||||
### 3) Web (`apps/web`)
|
* start bot
|
||||||
|
* stop bot
|
||||||
|
* restart bot
|
||||||
|
* Reconnexion automatique
|
||||||
|
* Logs runtime en base
|
||||||
|
|
||||||
- Pages principales:
|
---
|
||||||
- `/login`
|
|
||||||
- `/dashboard`
|
|
||||||
- Dashboard utilisateur:
|
|
||||||
- Ajouter un bot (token)
|
|
||||||
- Voir la liste des bots du tenant
|
|
||||||
- `start / stop / restart`
|
|
||||||
|
|
||||||
## Schéma PostgreSQL (core SaaS)
|
### Web App (`apps/web`)
|
||||||
|
|
||||||
Migration: `database/migrations/0004_saas_multitenant.sql`
|
Dashboard SaaS :
|
||||||
|
|
||||||
- `tenants`
|
* Login Discord OAuth
|
||||||
- `id` (UUID)
|
* Liste des bots du tenant
|
||||||
- `owner_user_id`
|
* Création de bot via token
|
||||||
- `users`
|
* Contrôle runtime (start / stop / restart)
|
||||||
- `tenant_id` FK
|
* Interface multi-langue (i18n)
|
||||||
- `discord_user_id` (unique)
|
|
||||||
- `role`
|
|
||||||
- `bots`
|
|
||||||
- `tenant_id` FK
|
|
||||||
- `owner_user_id` FK
|
|
||||||
- `discord_bot_id` (unique global)
|
|
||||||
- `token_ciphertext`, `token_iv`, `token_tag`
|
|
||||||
- `status`, `last_error`
|
|
||||||
- `bot_runtime_events`
|
|
||||||
- logs runtime par bot + tenant
|
|
||||||
|
|
||||||
Les tables legacy de configuration (`bot_presence_states`, `bot_member_message_configs`, `bot_log_event_configs`) sont enrichies avec `tenant_id` et `owner_user_id` pour respecter l'isolation multi-tenant stricte.
|
---
|
||||||
|
|
||||||
## API Principale
|
## 🗄️ Base de données
|
||||||
|
|
||||||
### Auth
|
### Multi-tenant strict
|
||||||
|
|
||||||
- `GET /auth/discord/login`
|
Tables principales :
|
||||||
- `GET /auth/discord/callback`
|
|
||||||
- `POST /auth/logout`
|
|
||||||
- `GET /api/me`
|
|
||||||
|
|
||||||
### Bots
|
* `tenants`
|
||||||
|
* `users`
|
||||||
|
* `bots`
|
||||||
|
* `bot_runtime_events`
|
||||||
|
|
||||||
- `GET /api/bots`
|
### Sécurité
|
||||||
- `POST /api/bots`
|
|
||||||
- body: `{ token: string, displayName?: string }`
|
|
||||||
- `POST /api/bots/:botId/start`
|
|
||||||
- `POST /api/bots/:botId/stop`
|
|
||||||
- `POST /api/bots/:botId/restart`
|
|
||||||
|
|
||||||
Tous ces endpoints sont tenant-scopés via la session.
|
* Isolation totale via `tenant_id`
|
||||||
|
* Tokens Discord chiffrés (AES-256-GCM)
|
||||||
|
* Logs séparés par tenant
|
||||||
|
|
||||||
## Sécurité
|
---
|
||||||
|
|
||||||
- Tokens bot jamais stockés en clair
|
## 🔐 Sécurité
|
||||||
- AES-256-GCM avec `TOKEN_ENCRYPTION_KEY` (32 bytes en base64)
|
|
||||||
- Validation token côté Discord avant insertion
|
|
||||||
- Session auth via JWT httpOnly cookie
|
|
||||||
- Filtrage systématique des requêtes par `tenant_id`
|
|
||||||
- Clés Redis namespacées par tenant
|
|
||||||
- Rate limiting par tenant sur les actions de contrôle
|
|
||||||
|
|
||||||
## Docker Compose (fixe)
|
* 🔒 Tokens bot jamais stockés en clair
|
||||||
|
* 🍪 JWT en cookie httpOnly
|
||||||
|
* 🧱 Isolation complète multi-tenant
|
||||||
|
* ⚡ Rate limiting par tenant
|
||||||
|
* 🧩 Redis namespaced
|
||||||
|
* 🚫 Aucun bot exposé individuellement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐳 Docker architecture
|
||||||
|
|
||||||
Services :
|
Services :
|
||||||
|
|
||||||
- `web`
|
* `web`
|
||||||
- `api`
|
* `api`
|
||||||
- `bot`
|
* `bot`
|
||||||
- `postgres`
|
* `postgres`
|
||||||
- `redis`
|
* `redis`
|
||||||
|
|
||||||
Pas de service par bot. Pas de `.env` par bot.
|
👉 Important :
|
||||||
|
Aucun container par bot → tout est centralisé
|
||||||
|
|
||||||
## Démarrage local
|
---
|
||||||
|
|
||||||
1. Copier l'environnement:
|
## 🚀 Installation
|
||||||
|
|
||||||
|
### 1. Cloner le projet
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/ArthurP-fr/Flint.git
|
||||||
|
cd Flint
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Configurer l’environnement
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Générer une clé de chiffrement valide (32 bytes base64):
|
---
|
||||||
|
|
||||||
|
### 3. Générer clé de chiffrement
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
openssl rand -base64 32
|
openssl rand -base64 32
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Installer les dépendances monorepo:
|
---
|
||||||
|
|
||||||
|
### 4. Installer les dépendances
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Lancer la stack complète:
|
---
|
||||||
|
|
||||||
|
### 5. Lancer la stack
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Dashboard:
|
---
|
||||||
|
|
||||||
- `http://localhost:3000`
|
## 🌍 Accès
|
||||||
|
|
||||||
API:
|
* 🌐 Web : [http://localhost:3000](http://localhost:3000)
|
||||||
|
* ⚙️ API : [http://localhost:4000/health](http://localhost:4000/health)
|
||||||
|
|
||||||
- `http://localhost:4000/health`
|
---
|
||||||
|
|
||||||
Bot manager health:
|
## 📡 API
|
||||||
|
|
||||||
- `http://localhost:4100/health`
|
### Auth
|
||||||
|
|
||||||
## Notes Scalabilité
|
* `GET /auth/discord/login`
|
||||||
|
* `GET /auth/discord/callback`
|
||||||
|
* `POST /auth/logout`
|
||||||
|
* `GET /api/me`
|
||||||
|
|
||||||
- Une instance bot unique peut gérer des dizaines/centaines de bots selon ressources.
|
### Bots
|
||||||
- Pour monter en charge horizontalement:
|
|
||||||
- scaler `apps/api`
|
* `GET /api/bots`
|
||||||
- scaler `apps/bot` avec coordination queue/locks
|
* `POST /api/bots`
|
||||||
- conserver Redis + PostgreSQL managés
|
* `POST /api/bots/:botId/start`
|
||||||
|
* `POST /api/bots/:botId/stop`
|
||||||
|
* `POST /api/bots/:botId/restart`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Scalabilité
|
||||||
|
|
||||||
|
Flint est conçu pour être scalable horizontalement :
|
||||||
|
|
||||||
|
* API → scalable horizontal
|
||||||
|
* Bot manager → scalable avec Redis coordination
|
||||||
|
* PostgreSQL → recommandé managé
|
||||||
|
* Redis → central queue system
|
||||||
|
|
||||||
|
👉 Un seul bot service peut gérer **des centaines de bots Discord**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 🖼️ Screenshots
|
||||||
|
|
||||||
|
### Home
|
||||||
|

|
||||||
|
|
||||||
|
### Bots
|
||||||
|

|
||||||
|
|
||||||
|
### Login
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Objectif du projet
|
||||||
|
|
||||||
|
Flint vise à devenir une plateforme type :
|
||||||
|
|
||||||
|
> “Discord Bot as a Service”
|
||||||
|
|
||||||
|
avec une architecture proche d’un SaaS moderne (Vercel / Stripe style backend design).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⭐ Points forts
|
||||||
|
|
||||||
|
* Multi-tenant natif
|
||||||
|
* Runtime dynamique de bots
|
||||||
|
* Sécurité forte (chiffrement + isolation)
|
||||||
|
* Queue distribuée (BullMQ + Redis)
|
||||||
|
* Architecture scalable dès le départ
|
||||||
|
|||||||
@@ -12,13 +12,14 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@saas/shared": "*",
|
"@saas/shared": "*",
|
||||||
"bullmq": "^5.21.2",
|
"bullmq": "^5.76.1",
|
||||||
"cookie-parser": "^1.4.7",
|
"cookie-parser": "^1.4.7",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"express": "^4.21.2",
|
"express": "^4.21.2",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"jose": "^5.9.6",
|
"jose": "^5.9.6",
|
||||||
|
"next": "15.5.15",
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.13.3",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -12,10 +12,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@napi-rs/canvas": "^0.1.98",
|
"@napi-rs/canvas": "^0.1.98",
|
||||||
"@saas/shared": "*",
|
"@saas/shared": "*",
|
||||||
"bullmq": "^5.21.2",
|
"bullmq": "^5.76.1",
|
||||||
"discord.js": "^14.17.3",
|
"discord.js": "^14.17.3",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
|
"next": "15.5.15",
|
||||||
"pg": "^8.13.3",
|
"pg": "^8.13.3",
|
||||||
"pino": "^10.3.1",
|
"pino": "^10.3.1",
|
||||||
"zod": "^3.24.1"
|
"zod": "^3.24.1"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default async function Footer() {
|
|||||||
<div className="text-sm text-[var(--foreground-muted)]">
|
<div className="text-sm text-[var(--foreground-muted)]">
|
||||||
<a
|
<a
|
||||||
className="transition-colors hover:text-[var(--foreground)]"
|
className="transition-colors hover:text-[var(--foreground)]"
|
||||||
href="https://github.com/"
|
href="https://github.com/ArthurP-fr/Flint"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "15.1.2",
|
"next": "^15.5.15",
|
||||||
"next-intl": "^4.9.1",
|
"next-intl": "^4.9.1",
|
||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0"
|
"react-dom": "19.0.0"
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 946 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 645 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
Generated
+561
-226
File diff suppressed because it is too large
Load Diff
@@ -35,5 +35,9 @@
|
|||||||
"tsx": "^4.19.3",
|
"tsx": "^4.19.3",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"typescript-eslint": "^8.59.0"
|
"typescript-eslint": "^8.59.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^16.2.4",
|
||||||
|
"uuid": "^14.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -2,13 +2,13 @@
|
|||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "packages/shared"
|
"path": "./packages/shared"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "apps/api"
|
"path": "./apps/api"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "apps/bot"
|
"path": "./apps/bot"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user