Skip to content
Open
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
86 changes: 85 additions & 1 deletion documentation.md
Original file line number Diff line number Diff line change
@@ -1 +1,85 @@
# documentation file
# Database Schema & Migration Module

## Overview

This module implements the database layer for a project management system using SQLite and Knex.js.

Includes:
- Database configuration
- migrations
- Seed data
- ER diagram

### Backend

- Node.js
- Knex.js

### Database

- SQLite

## Project Structure
text
task-4-database-schema/
├── src/
│ ├── config/
│ │ └── db.js
│ ├── migrations/
│ │ ├── create_users.js
│ │ ├── create_projects.js
│ │ └── create_project_events.js
│ └── seeds/
│ └── seed_initial_data.js
├── database.sqlite
├── knexfile.js
├── README.md
├── ER_DIAGRAM.md
└── documentation.md

## Database Schema

### Users
- id (Primary Key)
- name
- email (Unique)
- role

### Projects
- id (Primary Key)
- name
- description
- status
- owner_id (Foreign Key → Users.id)

### Project Events
- id (Primary Key)
- project_id (Foreign Key → Projects.id)
- event_type
- description
- created_at

## Relationships
- One User can own multiple Projects.
- One Project can contain multiple Project Events.

### Install

```bash
npm install

### Run Migrations

```bash
npx knex migrate:latest

### Run Seed Data

```bash
npx knex seed:run

## Features
- Normalized database schema
- Foreign key relationships
- Migration-based schema management
- Seed data for testing
25 changes: 25 additions & 0 deletions task-4-database-schema/ER_DIAGRAM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# ER Diagram - Shipyard Task 4

## Users
- id (PK)
- name
- email
- role

## Projects
- id (PK)
- name
- description
- status
- owner_id (FK -> Users.id)

## Project_Events
- id (PK)
- project_id (FK -> Projects.id)
- event_type
- description
- created_at

### Relationships
- Users (1) ----< Projects
- Projects (1) ----< Project_Events
27 changes: 27 additions & 0 deletions task-4-database-schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Shipyard Technical Evaluation - Task 4

## Tech Stack
- Express.js
- SQLite
- Knex

## Installation

```bash
npm install

## Run Migrations

```bash
npx knex migrate:latest

## Run Seeds

```bash
npx knex seed:run

## Schema

Users -> Projects -> Project Events
See ER_DIAGRAM.md for details

Binary file added task-4-database-schema/database.sqlite
Binary file not shown.
Empty file.
15 changes: 15 additions & 0 deletions task-4-database-schema/knexfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
development: {
client: "sqlite3",
connection: {
filename: "./database.sqlite",
},
useNullAsDefault: true,
migrations: {
directory: "./src/migrations",
},
seeds: {
directory: "./src/seeds",
},
},
};
18 changes: 18 additions & 0 deletions task-4-database-schema/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "task4db",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"express": "^5.2.1",
"knex": "^3.2.10",
"sqlite3": "^6.0.1"
}
}
11 changes: 11 additions & 0 deletions task-4-database-schema/src/config/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const knex = require("knex");

const db = knex({
client: "sqlite3",
connection: {
filename: "./database.sqlite",
},
useNullAsDefault: true,
});

module.exports = db;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable("users", (table) => {
table.increments("id").primary();
table.string("name");
table.string("email").unique();
table.string("role");
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable("users");
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable("projects", (table) => {
table.increments("id").primary();
table.string("name");
table.text("description");
table.string("status");
table
.integer("owner_id")
.unsigned()
.references("id")
.inTable("users");
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable("projects");
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function(knex) {
return knex.schema.createTable("project_events", (table) => {
table.increments("id").primary();
table
.integer("project_id")
.unsigned()
.references("id")
.inTable("projects");
table.string("event_type");
table.text("description");
table.timestamp("created_at").defaultTo(knex.fn.now());
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function(knex) {
return knex.schema.dropTable("project_events");
};
22 changes: 22 additions & 0 deletions task-4-database-schema/src/seeds/seed_initial_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
exports.seed = async function (knex) {
// Deletes ALL existing entries
await knex("project_events").del();
await knex("projects").del();
await knex("users").del();

// Insert sample users
await knex("users").insert([
{ id: 1, name: "John", email: "john@example.com", role: "admin" },
{ id: 2, name: "Sarah", email: "sarah@example.com", role: "developer" }
]);

// Insert sample projects
await knex("projects").insert([
{ id: 1, name: "Shipyard Project", description: "Sample Project", status: "active", owner_id: 1 }
]);

// Insert sample project events
await knex("project_events").insert([
{ id: 1, project_id: 1, event_type: "Created", description: "Project created" }
]);
};