Added Docker

This commit is contained in:
Tiemen van Olst
2025-09-09 08:52:28 +02:00
parent 7f1595dddd
commit 72d9f5e642
29 changed files with 10623 additions and 193 deletions

View File

@@ -0,0 +1,16 @@
import { sequelize } from '~/server/database'
export default defineEventHandler(async (event) => {
try {
// Import and run migrations
const { execSync } = await import('child_process')
execSync('npx sequelize-cli db:migrate', { stdio: 'inherit' })
return { success: true, message: 'Database migrated successfully' }
} catch (error) {
throw createError({
statusCode: 500,
statusMessage: 'Failed to migrate database'
})
}
})

View File

@@ -0,0 +1,20 @@
import { Post, User } from '~/server/database/models'
export default defineEventHandler(async (event) => {
try {
const posts = await Post.findAll({
include: [{
model: User,
as: 'author'
}],
order: [['createdAt', 'DESC']]
})
return posts
} catch (error) {
throw createError({
statusCode: 500,
statusMessage: 'Failed to fetch posts'
})
}
})

View File

@@ -0,0 +1,29 @@
import { Post, User } from '~/server/database/models'
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const post = await Post.create({
title: body.title,
content: body.content,
published: body.published || false,
authorId: body.authorId
})
// Get the post with author information
const postWithAuthor = await Post.findByPk(post.id, {
include: [{
model: User,
as: 'author'
}]
})
return postWithAuthor
} catch (error) {
throw createError({
statusCode: 500,
statusMessage: 'Failed to create post'
})
}
})

View File

@@ -0,0 +1,19 @@
import { User, Post } from '~/server/database/models';
export default defineEventHandler(async (event) => {
try {
const users = await User.findAll({
include: [{
model: Post,
as: 'posts'
}]
})
return users
} catch (error) {
console.error('Error fetching users:', error);
throw createError({
statusCode: 500,
statusMessage: 'Failed to fetch users'
})
}
})

View File

@@ -0,0 +1,19 @@
import { User } from '~/server/database/models'
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const user = await User.create({
email: body.email,
name: body.name
})
return user
} catch (error) {
throw createError({
statusCode: 500,
statusMessage: 'Failed to create user'
})
}
})

28
server/database/config.js Normal file
View File

@@ -0,0 +1,28 @@
require('dotenv').config();
module.exports = {
development: {
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mariadb'
},
test: {
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mariadb'
},
production: {
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
port: process.env.DB_PORT,
dialect: 'mariadb'
}
};

11
server/database/index.js Normal file
View File

@@ -0,0 +1,11 @@
import { Sequelize } from 'sequelize';
const config = useRuntimeConfig();
// Initialize Sequelize instance
const sequelize = new Sequelize(config.database, config.username, config.password, {
host: config.host,
dialect: config.dialect,
logging: config.logging || false,
});
export { sequelize };

View File

@@ -0,0 +1,35 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
email: {
type: Sequelize.STRING,
allowNull: false,
unique: true
},
name: {
type: Sequelize.STRING,
allowNull: true
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('users');
}
};

View File

@@ -0,0 +1,46 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('posts', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING,
allowNull: false
},
content: {
type: Sequelize.TEXT,
allowNull: true
},
published: {
type: Sequelize.BOOLEAN,
defaultValue: false
},
authorId: {
type: Sequelize.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id'
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('posts');
}
};

View File

@@ -0,0 +1,37 @@
import { DataTypes } from 'sequelize';
import { sequelize } from '../index.js';
const Post = sequelize.define('Post', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
title: {
type: DataTypes.STRING,
allowNull: false
},
content: {
type: DataTypes.TEXT,
allowNull: true
},
published: {
type: DataTypes.BOOLEAN,
defaultValue: false
},
authorId: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'users',
key: 'id'
}
}
}, {
tableName: 'posts',
timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt'
});
export default Post;

View File

@@ -0,0 +1,26 @@
import { DataTypes } from 'sequelize';
import { sequelize } from '../index.js';
const User = sequelize.define('User', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
name: {
type: DataTypes.STRING,
allowNull: true
}
}, {
tableName: 'users',
timestamps: true,
createdAt: 'createdAt',
updatedAt: 'updatedAt'
});
export default User;

View File

@@ -0,0 +1,8 @@
import User from './User.js';
import Post from './Post.js';
// Define associations
User.hasMany(Post, { foreignKey: 'authorId', as: 'posts' });
Post.belongsTo(User, { foreignKey: 'authorId', as: 'author' });
export { User, Post };