Skip to content

feat(dynamoDB): add service #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 213 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
# Projet Atlas – GenAI

Ce repository contient un projet web complet, composé d’un backend (API REST construite sur Fastify & Prisma) et d’un frontend (React + Vite). Il inclut également des workflows GitHub pour l’intégration et le déploiement continus, ainsi qu’une configuration pour Docker. Le but est de proposer un socle fonctionnel pour développer des applications web, avec une séparation claire entre le front et le back, et un outillage complet (tests, scripts d’init, linting, etc.).

## Table des matières

1. [Aperçu du projet](#aperçu-du-projet)
2. [Arborescence générale](#arborescence-générale)
3. [Prérequis](#prérequis)
4. [Installation et configuration](#installation-et-configuration)
- [Configuration des variables d’environnement](#configuration-des-variables-denvironnement)
5. [Lancer le projet](#lancer-le-projet)
- [Lancer le backend](#lancer-le-backend)
- [Lancer le frontend](#lancer-le-frontend)
- [Utiliser Docker](#utiliser-docker)
6. [Scripts utiles](#scripts-utiles)
7. [CI/CD – GitHub Workflows](#cicd--github-workflows)
8. [Contribuer](#contribuer)
9. [Licence](#licence)

---

## 1. Aperçu du projet

- **Backend** :
- Basé sur [Fastify](https://www.fastify.io/) et [Prisma](https://www.prisma.io/) (avec PostgreSQL).
- Gère l’authentification JWT, la pagination, la configuration de CORS/Helmet, un système de gestion d’erreurs centralisé et la documentation Swagger intégrée.
- Déploiement possible via Docker et Docker Compose, ou [Serverless](https://www.serverless.com/) (AWS Lambda par exemple).

- **Frontend** :
- Développé en [React](https://reactjs.org/) + [Vite](https://vitejs.dev/).
- Inclut un exemple de chat en temps réel, une gestion de la navigation avec React Router, un système de Tchat via WebSocket, ainsi que quelques composants d’interface (Sidebar, Layout Dashboard, etc.).
- Configuré avec ESLint, Prettier, TypeScript, etc.
- Prévu pour être déployé sur un hébergement statique (ou via Serverless Finch / CloudFront-S3).

- **Workflows GitHub** :
- *ci-frontend.yml* : Exécute la CI du frontend, avec installation, tests, build, etc.
- *cd-frontend-deployment.yml* : Déploiement continu du frontend sur un environnement défini (S3, etc.).

---

## 2. Arborescence générale

```
redboarddev-atlas-genai/
├── README.md # (ce fichier)
├── backend/
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── package.json
│ ├── serverless.yml
│ ├── tsconfig.json
│ ├── app/
│ │ ├── app.ts # Point d’entrée Fastify
│ │ ├── env/
│ │ │ └── .env_example
│ │ └── src/
│ │ ├── routes/
│ │ ├── services/
│ │ ├── middlewares/
│ │ ├── libs/
│ │ ├── entities/
│ │ ├── config/
│ │ └── ...
│ ├── prisma/
│ │ ├── schema.prisma
│ │ └── .env_example
│ └── usefull-scripts/
│ ├── generate-local.sh
│ ├── init-docker.sh
│ ├── migrate-local.sh
│ ├── start-docker.sh
│ └── stop_docker.sh
├── frontend/
│ ├── Dockerfile
│ ├── vite.config.ts
│ ├── package.json
│ ├── public/
│ │ └── locales/ # Fichiers de traduction (i18n)
│ └── src/
│ ├── App.tsx
│ ├── components/
│ ├── services/
│ ├── routes/
│ └── ...
└── .github/
└── workflows/
├── ci-frontend.yml
└── cd-frontend-deployment.yml
```

---

## 3. Prérequis

Pour utiliser ce projet localement ou lancer la CI/CD, vous aurez besoin des éléments suivants :

- **Node.js** ≥ 18.x
- **npm** ≥ 8.x (fourni avec Node.js), ou **yarn**
- **Docker** ≥ 20.10 (si vous utilisez Docker)
- **Docker Compose** ≥ 1.29 (pour le docker-compose.yml du backend)
- **Serverless CLI** (optionnel, si vous comptez déployer sur AWS Lambda)
```bash
npm install -g serverless
```

---

## 4. Installation et configuration

1. **Cloner le repository**

```bash
git clone https://github.com/votre-nom-utilisateur/redboarddev-atlas-genai.git
cd redboarddev-atlas-genai
```

2. **Installer les dépendances**
- Pour le backend :
```bash
cd backend
npm install
```
- Pour le frontend :
```bash
cd ../frontend
npm install
```

### Configuration des variables d’environnement

- **Backend**
- Dans `backend/app/env/.env_example`, vous trouverez un exemple de configuration des variables nécessaires (API_PORT, POSTGRES_USER, POSTGRES_PASSWORD, etc.).
- Copiez le fichier en `.env` et adaptez-le à votre environnement :

```bash
cp backend/app/env/.env_example backend/app/env/.env
```

- Faites de même pour `prisma/.env_example` si nécessaire (DATABASE_URL, etc.).

- **Frontend**
- Il peut exister un équivalent `.env` pour définir l’URL de l’API, etc.
- Reportez-vous à `frontend/config/stages-urls.json` ou `editApiUrl.js` si vous souhaitez personnaliser les URLs en fonction de l’environnement.

---

## 5. Lancer le projet

### Lancer le backend

Vous pouvez lancer le backend soit directement en local (Node.js), soit via Docker.

#### En local (Node.js)

1. Rendez-vous dans le dossier `backend`.
2. Assurez-vous que votre base de données est accessible (via docker ou un service local).
3. Exécutez :
```bash
npm run dev
```
4. L’API est normalement accessible sur [http://localhost:3000](http://localhost:3000) (ou le port configuré dans votre `.env`).

#### Lancer le frontend

Dans le dossier `frontend` :

1. Démarrez le serveur de développement :
```bash
npm run dev
```
2. Accédez ensuite à l’URL fournie dans la console (souvent [http://localhost:5173](http://localhost:5173)).

### Utiliser Docker

Le projet peut aussi être lancé via Docker Compose pour le backend. Les scripts se trouvent dans `backend/usefull-scripts`.

1. **Démarrer les conteneurs** (backend + DB) :
```bash
cd backend
./usefull-scripts/start-docker.sh
```
2. **Initialiser la base de données** (migrations, seed) :
```bash
./usefull-scripts/init-docker.sh
```
3. **Vérifier** : l’API devrait répondre sur le port `API_PORT` défini dans votre `.env`.
4. Le frontend peut également être containerisé (Dockerfile dans `frontend`), selon votre workflow habituel. Un exemple de `docker-compose` unifié pourrait être ajouté si besoin.

---

## 6. Scripts utiles

- **Backend** :
- `npm run dev` : démarre le serveur Fastify en mode développement (watch).
- `npm run prisma:generate` : génère le client Prisma.
- `npm run prisma:migrate` : applique les migrations en mode dev.
- `npm run prisma:seed` : lance le script de seed.
- `npm run lint:check` / `lint:fix` : vérifie / corrige le code via ESLint.
- `npm run format:check` / `format:fix` : vérifie / formate via Prettier.

- **Frontend** :
- `npm run dev` : lance Vite en mode dev.
- `npm run build` : construit l’application pour la production.
- `npm run preview` : prévisualise le build.

- **Scripts Docker (backend/usefull-scripts)** :
- `start-docker.sh` : lance Docker Compose (API + Postgres).
- `stop_docker.sh` : stoppe et supprime les conteneurs.
- `init-docker.sh` : génère le client Prisma, exécute migrations et seed.
- `generate-local.sh`, `migrate-local.sh` : utilitaires pour générer le client Prisma et lancer des migrations en local.

---
4 changes: 2 additions & 2 deletions backend/app/src/config/rate-limit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import fastifyRateLimit from '@fastify/rate-limit';

export const setupRateLimit = (ffy: FastifyInstance): void => {
ffy.register(fastifyRateLimit, {
max: 100,
timeWindow: '15 minutes',
max: 250,
timeWindow: '5 minutes',
addHeaders: {
'x-ratelimit-limit': true,
'x-ratelimit-remaining': true,
Expand Down
23 changes: 23 additions & 0 deletions backend/app/src/entities/chat-entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FromSchema } from 'json-schema-to-ts';

export const createChatSchema = {
type: 'object',
properties: {
chatId: { type: 'string' },
prompt: { type: 'string' },
},
required: ['chatId', 'prompt'],
additionalProperties: false,
} as const;

export type CreateChatData = FromSchema<typeof createChatSchema>;

export const updateChatSchema = {
type: 'object',
properties: { prompt: { type: 'string' } },
required: ['prompt'],

additionalProperties: false,
} as const;

export type UpdateChatData = FromSchema<typeof updateChatSchema>;
4 changes: 2 additions & 2 deletions backend/app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { setupHelmet } from '@config/helmet';
import { setupDecorators } from '@config/decorators/setupDecorators';
import { setupCors } from '@config/cors';

dotenv.config({ path: path.resolve(__dirname, './env/.env') });
dotenv.config({ path: path.resolve(__dirname, '../env/.env') });

export const ffy = fastify({ logger: true });

Expand All @@ -29,7 +29,7 @@ export const setupServer = async (): Promise<void> => {

// swagger
setupSwagger(ffy);

// routes
ffy.register(apiRoutes);

Expand Down
16 changes: 16 additions & 0 deletions backend/app/src/routes/chat/create-chat/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FastifyReply, FastifyRequest } from 'fastify';
import { createNewChat } from '@services/chat-service';
import { HttpStatusCode } from '@enums/http-status-enums';

import { TBody } from './schemas';

const handler = async (req: FastifyRequest, res: FastifyReply): Promise<void> => {
const { chatId, prompt } = req.body as TBody;

await createNewChat(chatId, 'user', prompt);

return res.status(HttpStatusCode.created).send({ chatId, prompt });

};

export default handler;
23 changes: 23 additions & 0 deletions backend/app/src/routes/chat/create-chat/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FastifyInstance } from 'fastify';

import { headers, body, params, querystring, response } from './schemas';
import handler from './handler';

const createChat = async (app: FastifyInstance): Promise<void> => {
app.route({
method: 'POST',
url: '',
schema: {
tags: ['Chat'],
description: 'Create a chat',
headers,
body,
params,
querystring,
response,
},
handler,
});
};

export default createChat;
22 changes: 22 additions & 0 deletions backend/app/src/routes/chat/create-chat/schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FromSchema } from 'json-schema-to-ts';
import { createChatSchema } from '@entities/chat-entity';

export const body = createChatSchema;

export type TBody = FromSchema<typeof body>;

export const params = {} as const;

export type TParams = FromSchema<typeof params>;

export const headers = {} as const;

export type THeaders = FromSchema<typeof headers>;

export const querystring = {} as const;

export type TQuerystring = FromSchema<typeof querystring>;

export const response = {} as const;

export type TResponse = FromSchema<typeof response>;
13 changes: 13 additions & 0 deletions backend/app/src/routes/chat/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FastifyInstance } from 'fastify';

import updateChat from './update-chat';
import listChat from './list-chat';
import createChat from './create-chat';

const Chat = async (app: FastifyInstance): Promise<void> => {
app.register(createChat);
app.register(updateChat);
app.register(listChat);
};

export default Chat;
13 changes: 13 additions & 0 deletions backend/app/src/routes/chat/list-chat/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FastifyReply, FastifyRequest } from 'fastify';
import { getChat } from '@services/chat-service';
import { HttpStatusCode } from '@enums/http-status-enums';

const handler = async (req: FastifyRequest, res: FastifyReply): Promise<void> => {
const { chatId } = req.params as { chatId: string };

const chat = await getChat(chatId);

return res.status(HttpStatusCode.ok).send({ chatId, chat });
};

export default handler;
22 changes: 22 additions & 0 deletions backend/app/src/routes/chat/list-chat/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { FastifyInstance } from 'fastify';

import { headers, params, querystring, response } from './schemas';
import handler from './handler';

const listChat = async (app: FastifyInstance): Promise<void> => {
app.route({
method: 'GET',
url: '/:chatId',
schema: {
tags: ['Chat'],
description: 'List chat from chatId',
headers,
params,
querystring,
response,
},
handler,
});
};

export default listChat;
17 changes: 17 additions & 0 deletions backend/app/src/routes/chat/list-chat/schemas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FromSchema } from 'json-schema-to-ts';

export const params = {} as const;

export type TParams = FromSchema<typeof params>;

export const headers = {} as const;

export type THeaders = FromSchema<typeof headers>;

export const querystring = {} as const;

export type TQuerystring = FromSchema<typeof querystring>;

export const response = {} as const;

export type TResponse = FromSchema<typeof response>;
Loading