{"id":15131344,"url":"https://github.com/thesaltree/blog-platform-expressJs","last_synced_at":"2025-03-28T19:30:29.639Z","repository":{"id":252103080,"uuid":"839436194","full_name":"thesaltree/blog-platform-expressJs","owner":"thesaltree","description":"Personal blog platform","archived":false,"fork":false,"pushed_at":"2024-08-08T02:40:23.000Z","size":142,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-11T23:41:00.189Z","etag":null,"topics":["authentication-middleware","blog-platform","express","frontend","fullstack","mysql","next-cookies","nextjs","nodejs","react","relational-databases","responsive-design","styled-components"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thesaltree.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-07T15:50:31.000Z","updated_at":"2024-11-19T09:54:43.000Z","dependencies_parsed_at":"2024-09-26T03:40:54.037Z","dependency_job_id":null,"html_url":"https://github.com/thesaltree/blog-platform-expressJs","commit_stats":null,"previous_names":["thesaltree/blog-capital","thesaltree/blog-platform-expressjs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesaltree%2Fblog-platform-expressJs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesaltree%2Fblog-platform-expressJs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesaltree%2Fblog-platform-expressJs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thesaltree%2Fblog-platform-expressJs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thesaltree","download_url":"https://codeload.github.com/thesaltree/blog-platform-expressJs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246088287,"owners_count":20721655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication-middleware","blog-platform","express","frontend","fullstack","mysql","next-cookies","nextjs","nodejs","react","relational-databases","responsive-design","styled-components"],"created_at":"2024-09-26T03:40:47.489Z","updated_at":"2025-03-28T19:30:29.324Z","avatar_url":"https://github.com/thesaltree.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Personal Blog Platform\n\n## Table of Contents\n1. [Introduction](#Introduction)\n2. [Project Structure](#project-structure)\n3. [Prerequisites](#prerequisites)\n4. [Getting Started](#getting-started)\n5. [Application Components](#application-components)\n   - [Backend](#backend)\n   - [Frontend](#frontend)\n   - [Database](#database)\n6. [Authentication](#authentication)\n7. [Development](#development)\n8. [Testing](#testing)\n9. [Continuous Integration](#continuous-integration)\n10. [Troubleshooting](#troubleshooting)\n11. [Screenshots](#screenshots)\n\n## Introduction\nThis project is a monorepo containing a full-stack blog application with a Next.js frontend, Express.js backend, and MySQL database.\n\n\n![Screenshot 2024-08-08 at 0 45 25](https://github.com/user-attachments/assets/e9d054d6-3c34-43aa-a33b-349fa8d532d4)\n\n\n## Project Structure\nThe project follows a monorepo structure:\n\n```\nblog-capital/\n├── applications/\n│   ├── frontend/    # Next.js TypeScript frontend\n│   ├── backend/     # Express.js backend\n│   └── db/          # MySQL database scripts\n├── infrastructure/\n│   ├── k8s/         # Kubernetes configuration files (not implemented)\n│   └── terraform/   # Terraform configuration files (not implemented)\n|── .github/\n|   └── workflows/   # GitHub Actions CI/CD workflows\n└── docker-compose.yml\n```\n\n**Note:** Due to time constraints, the Kubernetes and Terraform configurations for deploying in a cloud environment are not implemented. The `docker-compose.yml` file is used to define the development environment.\n\n## Prerequisites\n- [Docker](https://www.docker.com/products/docker-desktop)\n- [Git](https://git-scm.com/downloads)\n- [Make](https://www.gnu.org/software/make/) (usually pre-installed on macOS and Linux)\n\n## Getting Started\n1. Clone the repository:\n   ```bash\n   git clone https://github.com/thesaltree/blog-capital\n   cd blog-capital\n   ```\n\n2. Build the project:\n   ```bash\n   make build\n   ```\n\n3. Start the development environment:\n   ```bash\n   make up\n   ```\n   This step takes time for initialization.\n\n4. Access the applications:\n   - Frontend: http://localhost:3001\n   - Backend: http://localhost:3000\n\n## Application Components\n\n### Backend\nThe Express.js backend provides the following API endpoints:\n\n- `POST /signup`: User registration\n- `POST /login`: User authentication\n- `GET /posts`: Retrieve all posts\n- `POST /post`: Create a new post\n- `GET /posts/:id`: Get details of a specific post\n- `GET /posts?author=:authorId`: Get all posts by a specific author\n\n### Frontend\nThe Next.js frontend includes the following pages:\n\n- `/`: Home page (SSR) - displays all posts\n- `/login`: Login page (CSR)\n- `/signup`: Signup page (CSR)\n- `/posts/:id`: Post details page (ISR)\n- `/posts/dashboard`: User dashboard (CSR) - create posts and view own posts\n- `/authors/:id`: Author posts (CSR) - filtered posts by author\n\n### Database\nThe application uses MySQL as its database. The schema is defined in `applications/db/init.sql`.\n\n#### Schema\n\n| Table Name | Column Name  | Data Type | Constraints                                           |\n|------------|--------------|-----------|-------------------------------------------------------|\n| user       | id           | INT       | PRIMARY KEY, AUTO_INCREMENT                           |\n|            | name         | VARCHAR(255)       | NOT NULL                                              |\n|            | email        | VARCHAR(255) | UNIQUE, NOT NULL                                      |\n|            | passwordHash | VARCHAR(255) | NOT NULL                                              |\n| post       | id           | INT       | PRIMARY KEY, AUTO_INCREMENT                           |\n|            | title        | VARCHAR(255) | NOT NULL                                              |\n|            | content      | TEXT      |                                                       |\n|            | authorId     | INT       | NOT NULL, FOREIGN KEY (references user.id)            |\n|            | createdAt    | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP                             |\n|            | updatedAt    | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |\n\n#### Indexes\n- `PRIMARY KEY` on `id` for both `user` and `post` tables\n- `UNIQUE` index on `user.email`\n- Index `idx_post_authorId` on `post.authorId` for improved query performance\n\n#### Relationships\n- `post.authorId` is a foreign key that references `user.id`, establishing a one-to-many relationship between users and posts.\n\n#### Initial Data\nThe `init.sql` script also includes sample data:\n- 3 users are created with example email addresses and hashed passwords\n- 5 posts are created and associated with three of the sample users\n\n#### Usage\nTo interact with the database during development:\n\n1. Access the database shell:\n   ```bash\n   make db-shell\n   ```\n\n2. Once in the MySQL shell, you can run queries, e.g.:\n   ```sql\n   SELECT * FROM user;\n   SELECT * FROM post;\n   ```\n\n\n## Authentication\nThe application uses JWT (JSON Web Tokens) for authentication. Tokens are stored in the cookies which is secure and works with sever-side checks and sent with each request to the backend. Passwords are hashed using bcrypt before storage in the mysqldb.\n\n## Development\nUse the following commands to manage the development environment:\n\n```bash\n# Start the development environment\nmake up\n\n# Stop the development environment\nmake down\n\n# View logs\nmake logs\n\n# Access the database shell\nmake db-shell\n\n# Clean up containers and volumes\nmake clean\n```\n\n## Testing\nFrontend tests have been written in Jest. Use the following command in the frontend directory to run tests:\n\n```bash\nnpm test\n```\n\n## Continuous Integration\nThis project uses GitHub Actions for continuous integration. The workflow includes the following steps:\n\n1. Install dependencies for both frontend and backend:\n   ```bash\n   npm install\n   ```\n\n2. Run linting for both frontend and backend:\n   ```bash\n   npm run lint\n   ```\n\n3. Run tests for the frontend:\n   ```bash\n   npm test\n   ```\n\nThese checks are automatically run on every push to the repository and pull request to ensure code quality and catch potential issues early.\n\n## Troubleshooting\nIf you encounter any issues:\n\n1. Ensure Docker is running and up-to-date\n2. Check the logs using `make logs`\n3. Try cleaning and rebuilding the environment:\n   ```bash\n   make clean\n   make build\n   make up\n   ```\n\n## Screenshots\n![Screenshot 2024-08-08 at 0 45 25](https://github.com/user-attachments/assets/c7c133da-9bd6-4fba-8673-5c7596b7d971)\n\n![Screenshot 2024-08-08 at 0 46 13](https://github.com/user-attachments/assets/d82fb26a-d220-41e1-b66f-91f2d8189d63)\n\n![Screenshot 2024-08-08 at 0 46 27](https://github.com/user-attachments/assets/d2b112eb-c576-424d-86fc-f6b34b72f9f2)\n\n![Screenshot 2024-08-08 at 0 46 59](https://github.com/user-attachments/assets/8a338258-2554-4f25-a8b4-e942c2ab9e39)\n\n![Screenshot 2024-08-08 at 0 47 26](https://github.com/user-attachments/assets/f68c2cdc-e795-4793-a3a8-e7d7253bed5f)\n\n![Screenshot 2024-08-08 at 0 47 57](https://github.com/user-attachments/assets/23f2b5f9-c36d-4cae-b999-84f8edee38be)\n\n![Screenshot 2024-08-08 at 0 44 53](https://github.com/user-attachments/assets/aa6d58e7-9f08-42ca-8d47-14ff38236103)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesaltree%2Fblog-platform-expressJs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthesaltree%2Fblog-platform-expressJs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthesaltree%2Fblog-platform-expressJs/lists"}