Skip to content

Latest commit

ย 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Portfolio CMS

A modern, headless portfolio CMS built with Keystone 6, Next.js 16, Prisma 7, GraphQL, and PostgreSQL.

The project provides a flexible content management backend for a personal portfolio, with Keystone handling the CMS and GraphQL API, Prisma providing database access, and PostgreSQL serving as the primary database.

โœจ Features

  • ๐Ÿ“ Keystone 6 headless CMS
  • โšก Next.js 16 and React 19
  • ๐ŸŸข Node.js runtime
  • ๐Ÿ”Œ Built-in GraphQL API
  • ๐Ÿ—„๏ธ Prisma 7 ORM
  • ๐Ÿ˜ PostgreSQL database
  • ๐Ÿ”— Prisma PostgreSQL adapter (@prisma/adapter-pg)
  • ๐Ÿ” Keystone authentication
  • ๐Ÿ‘ค User/session management
  • ๐Ÿ“„ Document field support
  • ๐Ÿ“Š GraphQL operation logging
  • โ˜๏ธ Suitable for serverless PostgreSQL deployments
  • ๐Ÿงฉ Schema separated from Keystone configuration
  • ๐Ÿ”„ Headless architecture for API-first content delivery

๐Ÿ—๏ธ Tech Stack

Technology Version / Role
Next.js 16.x โ€” Application framework
React 19.x โ€” UI library
Node.js JavaScript runtime
KeystoneJS 6.x โ€” Headless CMS
GraphQL API layer provided by Keystone
Prisma 7.x โ€” ORM and database toolkit
PostgreSQL Primary relational database
PrismaPg PostgreSQL driver adapter
TypeScript Application language

The project's dependencies include Keystone 6 core/authentication, Prisma 7, Next.js 16, React 19, and the PostgreSQL Prisma adapter.

๐Ÿงฉ Architecture

The application follows a headless CMS architecture:

                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚      Portfolio       โ”‚
                         โ”‚     Next.js App      โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚
                                    โ”‚ GraphQL
                                    โ–ผ
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚     Keystone 6       โ”‚
                         โ”‚     Headless CMS     โ”‚
                         โ”‚                      โ”‚
                         โ”‚  Authentication      โ”‚
                         โ”‚  Sessions            โ”‚
                         โ”‚  GraphQL API         โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚
                                    โ”‚ PrismaPg
                                    โ–ผ
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚       Prisma 7       โ”‚
                         โ”‚         ORM          โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚
                                    โ–ผ
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚     PostgreSQL       โ”‚
                         โ”‚   Serverless DB      โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Data Flow

  1. Content is managed through the Keystone Admin UI.
  2. Keystone exposes the content through its GraphQL API.
  3. GraphQL operations are handled by the Keystone backend.
  4. Keystone uses Prisma for database access.
  5. Prisma connects to PostgreSQL through the PrismaPg adapter.
  6. The Next.js application can consume the GraphQL API to render portfolio content.

The Keystone configuration explicitly uses the PostgreSQL provider and initializes PrismaPg with the POSTGRES_URL environment variable.

๐Ÿ“ Project Structure

The Keystone configuration separates the application into dedicated schema and authentication modules:

portfolio-cms/
โ”œโ”€โ”€ auth.ts                 # Authentication and session configuration
โ”œโ”€โ”€ keystone.ts             # Keystone application configuration
โ”œโ”€โ”€ schema.ts               # Keystone lists / content schema
โ”œโ”€โ”€ prisma/
โ”‚   โ””โ”€โ”€ migrations/         # Prisma database migrations
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ tsconfig.json
โ”œโ”€โ”€ .env                    # Local environment variables
โ””โ”€โ”€ README.md

The exact project structure may contain additional Next.js components, pages, utilities, and assets.

๐Ÿš€ Getting Started

Prerequisites

Make sure you have:

  • Node.js installed
  • npm or another Node.js package manager
  • A PostgreSQL database
  • Git

1. Clone the Repository

git clone <your-repository-url>

cd <project-directory>

2. Install Dependencies

npm install

The project runs Keystone's post-install setup automatically through the configured postinstall script.

3. Configure Environment Variables

Create a .env file in the project root:

POSTGRES_URL="postgresql://USER:PASSWORD@HOST:DATABASE"

The Keystone configuration reads the PostgreSQL connection string from:

POSTGRES_URL

For example:

POSTGRES_URL="postgresql://postgres:password@localhost:5432/portfolio"

Important: Never commit your .env file or database credentials to Git.

๐Ÿ—„๏ธ Database Setup

This project uses PostgreSQL with Prisma 7.

The Keystone configuration specifies:

provider: postgresql

and uses:

PrismaPg

as the Prisma PostgreSQL adapter.

Apply Production Migrations

The project provides a dedicated migration script:

npm run migrate

This executes:

prisma migrate deploy

Generate Prisma Client

If required during development:

npx prisma generate

โ–ถ๏ธ Development

Start the Keystone development server with:

npm run dev

The project defines this as:

keystone dev

Once running, Keystone's Admin UI and GraphQL API will be available according to your Keystone configuration.

๐Ÿ“ฆ Production

Build the application:

npm run build

The project maps this command to:

keystone build

Start the production server:

npm run start

which executes:

keystone start

๐Ÿ”Œ GraphQL API

Keystone provides the project's GraphQL API.

The API acts as the primary interface between the CMS data layer and consuming applications.

A typical query might look like:

query {
  projects {
    id
    title
    description
  }
}

The available queries, mutations, fields, and relationships depend on the lists defined in schema.ts.

GraphQL Monitoring

The Keystone configuration includes an Apollo plugin that logs GraphQL operations:

graphql operation <operation-name>

It also logs errors encountered during GraphQL requests.

This can be useful during development and debugging.

๐Ÿ” Authentication

Authentication is configured separately from the main Keystone configuration.

The project imports:

import { withAuth, session } from './auth.ts'

and wraps the Keystone configuration with:

withAuth(...)

while providing the configured session to Keystone. This keeps authentication and session configuration separate from the core CMS configuration.

๐Ÿ‘ค Development Admin User

The current development configuration contains an onConnect hook that checks whether any users exist.

If no users exist, it creates an initial administrator account:

Email:    admin@example.com
Name:     admin
Password: generated automatically

The password is generated randomly at startup and printed to the console.

โš ๏ธ Production Warning

The existing implementation explicitly warns that this automatic user creation is intended for development and should not be used in production.

Before deploying to production, remove or replace this initialization logic with a secure administrator provisioning process.

๐Ÿ“ Content Schema

Keystone loads the application's content schema from:

schema.ts

The main Keystone configuration imports:

import { lists } from './schema.ts'

and passes those lists into the Keystone configuration. This means your portfolio's content models and relationships can be maintained independently from the main Keystone configuration.

For example, your schema can contain models such as:

Portfolio
โ”œโ”€โ”€ Projects
โ”œโ”€โ”€ Skills
โ”œโ”€โ”€ Technologies
โ”œโ”€โ”€ Experience
โ”œโ”€โ”€ Education
โ”œโ”€โ”€ Categories
โ””โ”€โ”€ Users

The exact models should be documented from schema.ts.

๐Ÿ› ๏ธ Available Commands

Command Description
npm run dev Start Keystone development server
npm run build Build Keystone for production
npm run start Start production server
npm run migrate Deploy Prisma migrations
npm install Install dependencies and run Keystone post-install

These commands are defined directly in the project's package.json.

๐Ÿ”’ Security Considerations

Before deploying this CMS to production:

  • Use a secure PostgreSQL connection string.
  • Store secrets in environment variables.
  • Never commit .env files.
  • Remove the automatic development admin creation.
  • Use strong administrator credentials.
  • Configure appropriate Keystone access controls.
  • Restrict administrative access.
  • Use HTTPS in production.
  • Review GraphQL permissions and mutations.
  • Keep dependencies updated.
  • Avoid logging sensitive information.

โ˜๏ธ Deployment

The architecture is suitable for deployment using modern cloud and serverless infrastructure.

                         Internet
                            โ”‚
                            โ–ผ
                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚   Next.js App   โ”‚
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”‚
                         GraphQL
                            โ”‚
                            โ–ผ
                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚   Keystone 6    โ”‚
                   โ”‚   CMS + API     โ”‚
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                            โ”‚
                         Prisma
                            โ”‚
                            โ–ผ
                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                   โ”‚   PostgreSQL    โ”‚
                   โ”‚   Serverless    โ”‚
                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

For production deployment:

  1. Configure POSTGRES_URL.
  2. Install dependencies.
  3. Deploy database migrations.
  4. Build Keystone.
  5. Start the production server.
  6. Configure authentication and access control.
  7. Remove development-only admin initialization.

Example:

npm install
npm run migrate
npm run build
npm run start

๐Ÿ”„ Development Workflow

        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚  Keystone Admin   โ”‚
        โ”‚       UI          โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
                  โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚    GraphQL API    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
                  โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚     Prisma 7      โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
                  โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚    PostgreSQL     โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
                  โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚    Next.js App    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The separation between CMS, API, database, and frontend allows portfolio content to be consumed independently from the presentation layer.

๐Ÿ“Œ Why This Architecture?

Headless CMS

Keystone manages content independently from the frontend.

This makes it possible to reuse the same portfolio content across:

  • Web applications
  • Mobile applications
  • Multiple frontend applications
  • Static websites
  • External services
  • Future applications

GraphQL

GraphQL allows clients to request only the fields they need and provides a structured API for interacting with CMS data.

Prisma

Prisma provides a type-safe database layer between Keystone and PostgreSQL.

PostgreSQL

PostgreSQL provides a robust relational database for structured portfolio content and relationships.

๐Ÿ”ฎ Future Improvements

  • Keystone headless CMS
  • GraphQL API
  • PostgreSQL integration
  • Prisma ORM
  • Authentication
  • Session management
  • GraphQL error logging
  • Production administrator provisioning
  • Image optimization/CDN
  • SEO metadata management
  • Draft/publishing workflow
  • Content versioning
  • Automated tests
  • CI/CD pipeline
  • API documentation
  • Monitoring and observability

๐Ÿค Contributing

Contributions, suggestions, and improvements are welcome.

1. Fork the repository

2. Create a feature branch

git checkout -b feature/my-feature

3. Make your changes

4. Commit your changes

git commit -m "Add my feature"

5. Push your branch

git push origin feature/my-feature

6. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License, unless another license is specified by the repository.


๐Ÿ‘จโ€๐Ÿ’ป About

Portfolio CMS is a modern headless content management system designed to manage portfolio content through Keystone 6 and expose it through a GraphQL API.

The system combines:

Next.js + KeystoneJS + GraphQL + Prisma + PostgreSQL

to provide a flexible, API-first architecture that separates content management from content presentation.


Core Stack

Next.js 16
     +
KeystoneJS 6
     +
GraphQL
     +
Prisma 7
     +
PostgreSQL
     =
Modern Headless Portfolio CMS

About

Portfolio Content Management System (PoCMS)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages