Compare commits

...

2 Commits

Author SHA1 Message Date
magdo 86109cf48b backend feladat 2026-02-13 19:15:16 +01:00
magdo 622d4a3321 backend feladat 2026-02-13 19:14:10 +01:00
37 changed files with 3363 additions and 0 deletions
+6
View File
@@ -14,4 +14,10 @@
*.vrb *.vrb
*.synctex.gz *.synctex.gz
#nodejs
*/*/node_modules
*/*/node_modules
*/*/package-lock.json
*/*/yarn.lock
Thumbs.* Thumbs.*
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
{
"name": "elso-gyakorlat",
"version": "1.0.0",
"description": "",
"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('/user/:userId', (req, res) => postController.getByUserId(req, res));
router.get('/:id', (req, res) => postController.getById(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;
+36
View File
@@ -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',
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;
}
}
@@ -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;
}
}
@@ -0,0 +1,13 @@
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');
}
return result;
}
}
@@ -0,0 +1,8 @@
export class UpdatePostCommand {
constructor(id, title, content, author) {
this.id = id;
this.title = title;
this.content = content;
this.author = author;
}
}
@@ -0,0 +1,18 @@
export class UpdatePostCommandHandler {
constructor(postRepository) {
this.postRepository = postRepository;
}
async handle(command) {
const postData = {};
if (command.title) postData.title = command.title;
if (command.content) postData.content = command.content;
if (command.author) postData.author = command.author;
const result = await this.postRepository.update(command.id, postData);
if (!result) {
throw new Error('Post not found');
}
return result;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -0,0 +1,13 @@
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');
}
return result;
}
}
@@ -0,0 +1,8 @@
export class UpdateUserCommand {
constructor(id, name, email, age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
}
@@ -0,0 +1,18 @@
export class UpdateUserCommandHandler {
constructor(userRepository) {
this.userRepository = userRepository;
}
async handle(command) {
const userData = {};
if (command.name) userData.name = command.name;
if (command.email) userData.email = command.email;
if (command.age !== undefined) userData.age = command.age;
const result = await this.userRepository.update(command.id, userData);
if (!result) {
throw new Error('User not found');
}
return result;
}
}
@@ -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;
}
}