negyedik gyakorlat + megoldasok
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
.env
|
||||
*.log
|
||||
@@ -0,0 +1,119 @@
|
||||
# Első Gyakorlat - MINTA Megoldás
|
||||
|
||||
Ez a mappa tartalmazza az első gyakorlat **teljes, működő megoldását**.
|
||||
|
||||
## Amit implementáltunk:
|
||||
|
||||
### 1. **Layered Architecture** (Rétegezett Architektúra)
|
||||
- **API Layer**: Controllers, Routers - HTTP kérések kezelése
|
||||
- **Application Layer**: Commands, Queries, Handlers - Üzleti logika
|
||||
- **Domain Layer**: Interfaces (Repository pattern)
|
||||
- **Infrastructure Layer**: Repositories - Adatkezelés (JSON file-ok)
|
||||
|
||||
### 2. **CQRS Pattern** (Command Query Responsibility Segregation)
|
||||
- **Commands**: Írási műveletek (Create, Update, Delete)
|
||||
- **Queries**: Olvasási műveletek (GetAll, GetById)
|
||||
- **Handlers**: Command és Query végrehajtók
|
||||
|
||||
### 3. **Repository Pattern**
|
||||
- `IUserRepository` és `IPostRepository` interfészek
|
||||
- `UserRepository` és `PostRepository` implementációk
|
||||
- Adatok tárolása JSON file-okban
|
||||
|
||||
## Struktúra
|
||||
|
||||
```
|
||||
src/
|
||||
├── API/
|
||||
│ ├── server.js # Express szerver
|
||||
│ ├── controllers/
|
||||
│ │ ├── userController.js # User endpoint logika
|
||||
│ │ └── postController.js # Post endpoint logika
|
||||
│ └── routers/
|
||||
│ ├── userRouter.js # User route-ok
|
||||
│ └── postRouter.js # Post route-ok
|
||||
├── Application/
|
||||
│ ├── users/
|
||||
│ │ ├── command/ # User írási műveletek
|
||||
│ │ │ ├── createUserCommand.js
|
||||
│ │ │ ├── createUserCommandHandler.js
|
||||
│ │ │ ├── updateUserCommand.js
|
||||
│ │ │ ├── updateUserCommandHandler.js
|
||||
│ │ │ ├── deleteUserCommand.js
|
||||
│ │ │ └── deleteUserCommandHandler.js
|
||||
│ │ └── query/ # User olvasási műveletek
|
||||
│ │ ├── getAllUsersQuery.js
|
||||
│ │ ├── getAllUsersQueryHandler.js
|
||||
│ │ ├── getUserByIdQuery.js
|
||||
│ │ └── getUserByIdQueryHandler.js
|
||||
│ └── blogs/
|
||||
│ ├── command/ # Post írási műveletek
|
||||
│ └── query/ # Post olvasási műveletek
|
||||
├── Domain/
|
||||
│ ├── IUserRepository.js # User repository interface
|
||||
│ └── IPostRepository.js # Post repository interface
|
||||
└── Infrastructure/
|
||||
├── userRepository.js # User repository implementáció
|
||||
├── postRepository.js # Post repository implementáció
|
||||
├── user.json # User adatok
|
||||
└── post.json # Post adatok
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Users
|
||||
- `GET /api/users` - Összes user lekérése
|
||||
- `GET /api/users/:id` - Egy user lekérése
|
||||
- `POST /api/users` - Új user létrehozása
|
||||
- `PUT /api/users/:id` - User módosítása
|
||||
- `DELETE /api/users/:id` - User törlése
|
||||
|
||||
### Posts
|
||||
- `GET /api/posts` - Összes post lekérése
|
||||
- `GET /api/posts/:id` - Egy post lekérése
|
||||
- `GET /api/posts/user/:userId` - User összes postja
|
||||
- `POST /api/posts` - Új post létrehozása
|
||||
- `PUT /api/posts/:id` - Post módosítása
|
||||
- `DELETE /api/posts/:id` - Post törlése
|
||||
|
||||
## Indítás
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
A szerver elindul a `http://localhost:3000` címen.
|
||||
|
||||
## Példa Használat
|
||||
|
||||
### User létrehozása
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/users \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"age": 25
|
||||
}'
|
||||
```
|
||||
|
||||
### Post létrehozása
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/posts \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title": "My First Post",
|
||||
"content": "Hello World!",
|
||||
"author": "John Doe"
|
||||
}'
|
||||
```
|
||||
|
||||
## Tanulási Pontok
|
||||
|
||||
1. **Separation of Concerns**: Minden réteg saját felelősséggel rendelkezik
|
||||
2. **CQRS**: Írási és olvasási műveletek szétválasztása
|
||||
3. **Repository Pattern**: Adatkezelés absztrakciója
|
||||
4. **Dependency Injection**: Handler-ek megkapják a repository-t
|
||||
5. **Express.js**: RESTful API építése
|
||||
6. **File-based Storage**: JSON file-ok használata adatbázis helyett
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "elso-gyakorlat-minta",
|
||||
"version": "1.0.0",
|
||||
"description": "Complete reference implementation - First Exercise",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "nodemon src/API/server.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^5.2.1",
|
||||
"nodemon": "^3.1.11"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import { PostRepository } from '../../Infrastructure/postRepository.js';
|
||||
import { GetAllPostsQuery } from '../../Application/blogs/query/getAllPostsQuery.js';
|
||||
import { GetAllPostsQueryHandler } from '../../Application/blogs/query/getAllPostsQueryHandler.js';
|
||||
import { GetPostByIdQuery } from '../../Application/blogs/query/getPostByIdQuery.js';
|
||||
import { GetPostByIdQueryHandler } from '../../Application/blogs/query/getPostByIdQueryHandler.js';
|
||||
import { GetPostsByUserIdQuery } from '../../Application/blogs/query/getPostsByUserIdQuery.js';
|
||||
import { GetPostsByUserIdQueryHandler } from '../../Application/blogs/query/getPostsByUserIdQueryHandler.js';
|
||||
import { CreatePostCommand } from '../../Application/blogs/command/createPostCommand.js';
|
||||
import { CreatePostCommandHandler } from '../../Application/blogs/command/createPostCommandHandler.js';
|
||||
import { UpdatePostCommand } from '../../Application/blogs/command/updatePostCommand.js';
|
||||
import { UpdatePostCommandHandler } from '../../Application/blogs/command/updatePostCommandHandler.js';
|
||||
import { DeletePostCommand } from '../../Application/blogs/command/deletePostCommand.js';
|
||||
import { DeletePostCommandHandler } from '../../Application/blogs/command/deletePostCommandHandler.js';
|
||||
|
||||
const postRepository = new PostRepository();
|
||||
const getAllPostsQueryHandler = new GetAllPostsQueryHandler(postRepository);
|
||||
const getPostByIdQueryHandler = new GetPostByIdQueryHandler(postRepository);
|
||||
const getPostsByUserIdQueryHandler = new GetPostsByUserIdQueryHandler(postRepository);
|
||||
const createPostCommandHandler = new CreatePostCommandHandler(postRepository);
|
||||
const updatePostCommandHandler = new UpdatePostCommandHandler(postRepository);
|
||||
const deletePostCommandHandler = new DeletePostCommandHandler(postRepository);
|
||||
|
||||
export class PostController {
|
||||
async getAll(req, res) {
|
||||
try {
|
||||
const query = new GetAllPostsQuery();
|
||||
const posts = await getAllPostsQueryHandler.handle(query);
|
||||
res.json(posts);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async getById(req, res) {
|
||||
try {
|
||||
const query = new GetPostByIdQuery(req.params.id);
|
||||
const post = await getPostByIdQueryHandler.handle(query);
|
||||
res.json(post);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async getByUserId(req, res) {
|
||||
try {
|
||||
const query = new GetPostsByUserIdQuery(req.params.userId);
|
||||
const posts = await getPostsByUserIdQueryHandler.handle(query);
|
||||
res.json(posts);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async create(req, res) {
|
||||
try {
|
||||
const command = new CreatePostCommand(
|
||||
req.body.title,
|
||||
req.body.content,
|
||||
req.body.author
|
||||
);
|
||||
const post = await createPostCommandHandler.handle(command);
|
||||
res.status(201).json(post);
|
||||
} catch (error) {
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async update(req, res) {
|
||||
try {
|
||||
const command = new UpdatePostCommand(
|
||||
req.params.id,
|
||||
req.body.title,
|
||||
req.body.content,
|
||||
req.body.author
|
||||
);
|
||||
const post = await updatePostCommandHandler.handle(command);
|
||||
res.json(post);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async delete(req, res) {
|
||||
try {
|
||||
const command = new DeletePostCommand(req.params.id);
|
||||
await deletePostCommandHandler.handle(command);
|
||||
res.status(204).send();
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import { UserRepository } from '../../Infrastructure/userRepository.js';
|
||||
import { GetAllUsersQuery } from '../../Application/users/query/getAllUsersQuery.js';
|
||||
import { GetAllUsersQueryHandler } from '../../Application/users/query/getAllUsersQueryHandler.js';
|
||||
import { GetUserByIdQuery } from '../../Application/users/query/getUserByIdQuery.js';
|
||||
import { GetUserByIdQueryHandler } from '../../Application/users/query/getUserByIdQueryHandler.js';
|
||||
import { CreateUserCommand } from '../../Application/users/command/createUserCommand.js';
|
||||
import { CreateUserCommandHandler } from '../../Application/users/command/createUserCommandHandler.js';
|
||||
import { UpdateUserCommand } from '../../Application/users/command/updateUserCommand.js';
|
||||
import { UpdateUserCommandHandler } from '../../Application/users/command/updateUserCommandHandler.js';
|
||||
import { DeleteUserCommand } from '../../Application/users/command/deleteUserCommand.js';
|
||||
import { DeleteUserCommandHandler } from '../../Application/users/command/deleteUserCommandHandler.js';
|
||||
|
||||
const userRepository = new UserRepository();
|
||||
const getAllUsersQueryHandler = new GetAllUsersQueryHandler(userRepository);
|
||||
const getUserByIdQueryHandler = new GetUserByIdQueryHandler(userRepository);
|
||||
const createUserCommandHandler = new CreateUserCommandHandler(userRepository);
|
||||
const updateUserCommandHandler = new UpdateUserCommandHandler(userRepository);
|
||||
const deleteUserCommandHandler = new DeleteUserCommandHandler(userRepository);
|
||||
|
||||
export class UserController {
|
||||
async getAll(req, res) {
|
||||
try {
|
||||
const query = new GetAllUsersQuery();
|
||||
const users = await getAllUsersQueryHandler.handle(query);
|
||||
res.json(users);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async getById(req, res) {
|
||||
try {
|
||||
const query = new GetUserByIdQuery(req.params.id);
|
||||
const user = await getUserByIdQueryHandler.handle(query);
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async create(req, res) {
|
||||
try {
|
||||
const command = new CreateUserCommand(
|
||||
req.body.name,
|
||||
req.body.email,
|
||||
req.body.age
|
||||
);
|
||||
const user = await createUserCommandHandler.handle(command);
|
||||
res.status(201).json(user);
|
||||
} catch (error) {
|
||||
res.status(400).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async update(req, res) {
|
||||
try {
|
||||
const command = new UpdateUserCommand(
|
||||
req.params.id,
|
||||
req.body.name,
|
||||
req.body.email,
|
||||
req.body.age
|
||||
);
|
||||
const user = await updateUserCommandHandler.handle(command);
|
||||
res.json(user);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
|
||||
async delete(req, res) {
|
||||
try {
|
||||
const command = new DeleteUserCommand(req.params.id);
|
||||
await deleteUserCommandHandler.handle(command);
|
||||
res.status(204).send();
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: error.message });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import express from 'express';
|
||||
import { PostController } from '../controllers/postController.js';
|
||||
|
||||
const router = express.Router();
|
||||
const postController = new PostController();
|
||||
|
||||
router.get('/', (req, res) => postController.getAll(req, res));
|
||||
router.get('/:id', (req, res) => postController.getById(req, res));
|
||||
router.get('/user/:userId', (req, res) => postController.getByUserId(req, res));
|
||||
router.post('/', (req, res) => postController.create(req, res));
|
||||
router.put('/:id', (req, res) => postController.update(req, res));
|
||||
router.delete('/:id', (req, res) => postController.delete(req, res));
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,13 @@
|
||||
import express from 'express';
|
||||
import { UserController } from '../controllers/userController.js';
|
||||
|
||||
const router = express.Router();
|
||||
const userController = new UserController();
|
||||
|
||||
router.get('/', (req, res) => userController.getAll(req, res));
|
||||
router.get('/:id', (req, res) => userController.getById(req, res));
|
||||
router.post('/', (req, res) => userController.create(req, res));
|
||||
router.put('/:id', (req, res) => userController.update(req, res));
|
||||
router.delete('/:id', (req, res) => userController.delete(req, res));
|
||||
|
||||
export default router;
|
||||
@@ -0,0 +1,36 @@
|
||||
import express from 'express';
|
||||
import postRouter from './routers/postRouter.js';
|
||||
import userRouter from './routers/userRouter.js';
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3000;
|
||||
|
||||
// Middleware
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Routes
|
||||
app.use('/api/posts', postRouter);
|
||||
app.use('/api/users', userRouter);
|
||||
|
||||
// Root endpoint
|
||||
app.get('/', (req, res) => {
|
||||
res.json({
|
||||
message: 'Welcome to the Blog API - MINTA Megoldás',
|
||||
endpoints: {
|
||||
posts: '/api/posts',
|
||||
users: '/api/users'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Error handling middleware
|
||||
app.use((err, req, res, next) => {
|
||||
console.error(err.stack);
|
||||
res.status(500).json({ error: 'Something went wrong!' });
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server is running on http://localhost:${PORT}`);
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
export class CreatePostCommand {
|
||||
constructor(title, content, author) {
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.author = author;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
export class CreatePostCommandHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
if (!command.title || !command.content) {
|
||||
throw new Error('Title and content are required');
|
||||
}
|
||||
|
||||
const postData = {
|
||||
title: command.title,
|
||||
content: command.content,
|
||||
author: command.author
|
||||
};
|
||||
|
||||
return await this.postRepository.create(postData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export class DeletePostCommand {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
export class DeletePostCommandHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
const result = await this.postRepository.delete(command.id);
|
||||
if (!result) {
|
||||
throw new Error('Post not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export class UpdatePostCommand {
|
||||
constructor(id, title, content, author) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.content = content;
|
||||
this.author = author;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
export class UpdatePostCommandHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
const postData = {
|
||||
title: command.title,
|
||||
content: command.content,
|
||||
author: command.author
|
||||
};
|
||||
|
||||
const post = await this.postRepository.update(command.id, postData);
|
||||
if (!post) {
|
||||
throw new Error('Post not found');
|
||||
}
|
||||
|
||||
return post;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class GetAllPostsQuery {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export class GetAllPostsQueryHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(query) {
|
||||
return await this.postRepository.getAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export class GetPostByIdQuery {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export class GetPostByIdQueryHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(query) {
|
||||
const post = await this.postRepository.getById(query.id);
|
||||
if (!post) {
|
||||
throw new Error('Post not found');
|
||||
}
|
||||
return post;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export class GetPostsByUserIdQuery {
|
||||
constructor(userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
export class GetPostsByUserIdQueryHandler {
|
||||
constructor(postRepository) {
|
||||
this.postRepository = postRepository;
|
||||
}
|
||||
|
||||
async handle(query) {
|
||||
return await this.postRepository.getByUserId(query.userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export class CreateUserCommand {
|
||||
constructor(name, email, age) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
export class CreateUserCommandHandler {
|
||||
constructor(userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
if (!command.name || !command.email) {
|
||||
throw new Error('Name and email are required');
|
||||
}
|
||||
|
||||
const userData = {
|
||||
name: command.name,
|
||||
email: command.email,
|
||||
age: command.age
|
||||
};
|
||||
|
||||
return await this.userRepository.create(userData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export class DeleteUserCommand {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
export class DeleteUserCommandHandler {
|
||||
constructor(userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
const result = await this.userRepository.delete(command.id);
|
||||
if (!result) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export class UpdateUserCommand {
|
||||
constructor(id, name, email, age) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
export class UpdateUserCommandHandler {
|
||||
constructor(userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
async handle(command) {
|
||||
const userData = {
|
||||
name: command.name,
|
||||
email: command.email,
|
||||
age: command.age
|
||||
};
|
||||
|
||||
const user = await this.userRepository.update(command.id, userData);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class GetAllUsersQuery {
|
||||
constructor() {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export class GetAllUsersQueryHandler {
|
||||
constructor(userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
async handle(query) {
|
||||
return await this.userRepository.getAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export class GetUserByIdQuery {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export class GetUserByIdQueryHandler {
|
||||
constructor(userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
async handle(query) {
|
||||
const user = await this.userRepository.getById(query.id);
|
||||
if (!user) {
|
||||
throw new Error('User not found');
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
export class IPostRepository {
|
||||
async getAll() {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async getById(id) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async getByUserId(userId) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async create(post) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async update(id, postData) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async delete(id) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
export class IUserRepository {
|
||||
async getAll() {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async getById(id) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async create(user) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async update(id, userData) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
|
||||
async delete(id) {
|
||||
throw new Error('Method not implemented');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,65 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { IPostRepository } from '../Domain/IPostRepository.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const POST_FILE = path.join(__dirname, 'post.json');
|
||||
|
||||
export class PostRepository extends IPostRepository {
|
||||
async getAll() {
|
||||
try {
|
||||
const data = await fs.readFile(POST_FILE, 'utf-8');
|
||||
return JSON.parse(data);
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getById(id) {
|
||||
const posts = await this.getAll();
|
||||
return posts.find(post => post.id === id);
|
||||
}
|
||||
|
||||
async getByUserId(userId) {
|
||||
const posts = await this.getAll();
|
||||
return posts.filter(post => post.userId === userId);
|
||||
}
|
||||
|
||||
async create(post) {
|
||||
const posts = await this.getAll();
|
||||
const newPost = {
|
||||
id: Date.now().toString(),
|
||||
...post,
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
posts.push(newPost);
|
||||
await fs.writeFile(POST_FILE, JSON.stringify(posts, null, 2));
|
||||
return newPost;
|
||||
}
|
||||
|
||||
async update(id, postData) {
|
||||
const posts = await this.getAll();
|
||||
const index = posts.findIndex(post => post.id === id);
|
||||
if (index === -1) return null;
|
||||
|
||||
posts[index] = {
|
||||
...posts[index],
|
||||
...postData,
|
||||
id: posts[index].id,
|
||||
updatedAt: new Date().toISOString()
|
||||
};
|
||||
await fs.writeFile(POST_FILE, JSON.stringify(posts, null, 2));
|
||||
return posts[index];
|
||||
}
|
||||
|
||||
async delete(id) {
|
||||
const posts = await this.getAll();
|
||||
const filteredPosts = posts.filter(post => post.id !== id);
|
||||
if (posts.length === filteredPosts.length) return false;
|
||||
|
||||
await fs.writeFile(POST_FILE, JSON.stringify(filteredPosts, null, 2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,60 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { IUserRepository } from '../Domain/IUserRepository.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const USER_FILE = path.join(__dirname, 'user.json');
|
||||
|
||||
export class UserRepository extends IUserRepository {
|
||||
async getAll() {
|
||||
try {
|
||||
const data = await fs.readFile(USER_FILE, 'utf-8');
|
||||
return JSON.parse(data);
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getById(id) {
|
||||
const users = await this.getAll();
|
||||
return users.find(user => user.id === id);
|
||||
}
|
||||
|
||||
async create(user) {
|
||||
const users = await this.getAll();
|
||||
const newUser = {
|
||||
id: Date.now().toString(),
|
||||
...user,
|
||||
createdAt: new Date().toISOString()
|
||||
};
|
||||
users.push(newUser);
|
||||
await fs.writeFile(USER_FILE, JSON.stringify(users, null, 2));
|
||||
return newUser;
|
||||
}
|
||||
|
||||
async update(id, userData) {
|
||||
const users = await this.getAll();
|
||||
const index = users.findIndex(user => user.id === id);
|
||||
if (index === -1) return null;
|
||||
|
||||
users[index] = {
|
||||
...users[index],
|
||||
...userData,
|
||||
id: users[index].id,
|
||||
updatedAt: new Date().toISOString()
|
||||
};
|
||||
await fs.writeFile(USER_FILE, JSON.stringify(users, null, 2));
|
||||
return users[index];
|
||||
}
|
||||
|
||||
async delete(id) {
|
||||
const users = await this.getAll();
|
||||
const filteredUsers = users.filter(user => user.id !== id);
|
||||
if (users.length === filteredUsers.length) return false;
|
||||
|
||||
await fs.writeFile(USER_FILE, JSON.stringify(filteredUsers, null, 2));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user