Skip to content

Commit

Permalink
feat: added ability to include ID in url for fetching specific items,…
Browse files Browse the repository at this point in the history
… editing and deleting records (#38)

* chore: update tsconfig.json to include prisma path mapping

* chore: update package.json dependencies and bun.lockb file

* feat: add Zod generator to Prisma schema

* chore: update .gitignore to exclude generated Prisma files

* chore: rename api-responses to response-formatter

* feat: refactor route management and permissions system

* feat: implement API route handler class for improved request management

* refactor: remove deprecated schemas file

* chore: update docker-compose to use local volume for PostgreSQL data

* fix: update health API route to return detailed status response

* feat: enhance OpenAPI documentation with structured error responses and CRUD operations for dynamic routes

* feat: enhance OpenAPI configuration by adding query parameters for relation inclusion and updating hidden clients list

* feat: implement CRUD operations for dynamic routes with dedicated handlers for GET, POST, PUT, and DELETE methods

* refactor: simplify OpenAPI configuration by removing unnecessary query parameters and consolidating hidden clients list

* feat: extend ApiRouteHandler to support optional ID parameter for CRUD operations

* docs: update README to include API documentation link and additional resources

* feat: add GET method to dynamic route handler for improved API request management

* feat: enhance ApiRouteHandler to support GET requests with optional ID handling and improved error responses

* feat: add RouteConfig interface to define route permissions and metadata structure

* feat: enhance OpenAPI specification generation with structured error handling and CRUD operations for dynamic routes

* fix: removed linting step from build script in package.json

* chore: update Prettier configuration to enforce single quotes, trailing commas, and semicolons

* chore: update .gitignore to exclude Docker data directory

* chore: standardize quotes and update configuration files for consistency

* feat: add User route configuration with SENIOR_ONLY permissions

* feat: enhance OpenAPI specification to exclude sensitive fields from generated schemas

* feat: enhance ApiRouteHandler with type safety for routeConfig and auth,
  • Loading branch information
BramSuurdje authored Dec 18, 2024
1 parent e3ff5a6 commit f127791
Show file tree
Hide file tree
Showing 21 changed files with 1,072 additions and 953 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
!.yarn/releases
!.yarn/versions

# docker
/data

# testing
/coverage

Expand All @@ -29,6 +32,9 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

# prisma
prisma/generated

# env files
.env
.env.*
Expand Down
7 changes: 5 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"plugins": ["prettier-plugin-tailwindcss"]
}
"plugins": ["prettier-plugin-tailwindcss"],
"singleQuote": true,
"trailingComma": "all",
"semi": true
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ bun dev

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

Open [http://localhost:3000/api/v1/documentation](http://localhost:3000/api/v1/documentation) with your browser to see the full documentation for all the routes. (build on top of the OpenAPI specification)

## 🤔 Learn More

To learn more about Next.js, take a look at the following resources:
Expand All @@ -32,6 +34,7 @@ To learn more about Next.js, take a look at the following resources:
- [better-auth](https://better-auth.com/) - Authentication
- [prisma](https://prisma.io/) - Database ORM
- [pino](https://github.com/pinojs/pino) - Logging
- [scalar](https://scalar.com/) - Documentation

## 🚧 Commit Message Guidelines

Expand Down
Binary file modified bun.lockb
Binary file not shown.
28 changes: 14 additions & 14 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
export default {
extends: ["@commitlint/config-conventional"],
extends: ['@commitlint/config-conventional'],
rules: {
"type-enum": [
'type-enum': [
2,
"always",
'always',
[
"ci",
"chore",
"docs",
"ticket",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
'ci',
'chore',
'docs',
'ticket',
'feat',
'fix',
'perf',
'refactor',
'revert',
'style',
],
],
"header-max-length": [2, "always", 200],
'header-max-length': [2, 'always', 200],
},
};
9 changes: 3 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ services:
nextjs:
build: .
ports:
- "3000:3000"
- '3001:3000'
environment:
- NODE_ENV=production
restart: always
Expand All @@ -15,9 +15,6 @@ services:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
ports:
- "5432:5432"
- '5432:5432'
volumes:
- postgres-data:/var/lib/postgresql/data

volumes:
postgres-data:
- ./data/postgres:/var/lib/postgresql/data
42 changes: 21 additions & 21 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import antfu from "@antfu/eslint-config";
import nextPlugin from "@next/eslint-plugin-next";
import pluginQuery from "@tanstack/eslint-plugin-query";
import antfu from '@antfu/eslint-config';
import nextPlugin from '@next/eslint-plugin-next';
import pluginQuery from '@tanstack/eslint-plugin-query';

export default antfu(
{
type: "app",
type: 'app',
typescript: true,
formatters: true,
stylistic: {
indent: 2,
semi: true,
quotes: "single",
quotes: 'single',
},
plugins: {
"@tanstack/query": pluginQuery,
"@next/next": nextPlugin,
'@tanstack/query': pluginQuery,
'@next/next': nextPlugin,
},
extends: ["next/core-web-vitals", "next/typescript"],
extends: ['next/core-web-vitals', 'next/typescript'],
},
{
rules: {
"no-console": ["warn"],
"@tanstack/query/exhaustive-deps": ["error"],
"antfu/no-top-level-await": ["off"],
"node/prefer-global/process": ["off"],
"node/no-process-env": ["error"],
"unused-imports/no-unused-vars": ["off"],
"perfectionist/sort-imports": [
"error",
'no-console': ['warn'],
'@tanstack/query/exhaustive-deps': ['error'],
'antfu/no-top-level-await': ['off'],
'node/prefer-global/process': ['off'],
'node/no-process-env': ['error'],
'unused-imports/no-unused-vars': ['off'],
'perfectionist/sort-imports': [
'error',
{
internalPattern: ["@/**"],
internalPattern: ['@/**'],
},
],
"unicorn/filename-case": [
"error",
'unicorn/filename-case': [
'error',
{
case: "kebabCase",
ignore: ["README.md", ".*classes.*"],
case: 'kebabCase',
ignore: ['README.md', '.*classes.*'],
},
],
},
Expand Down
6 changes: 3 additions & 3 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { NextConfig } from "next";
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
output: "standalone",
serverExternalPackages: ["pino", "pino-pretty"],
output: 'standalone',
serverExternalPackages: ['pino', 'pino-pretty'],
experimental: {
// typedRoutes: true,
},
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "bun run lint:fix && prisma generate && next build",
"build": "prisma generate && next build",
"start": "next start",
"lint": "eslint .",
"lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
Expand All @@ -27,9 +27,9 @@
"clsx": "^2.1.1",
"dotenv": "^16.4.5",
"dotenv-expand": "^12.0.1",
"lucide-react": "^0.468.0",
"http-status-codes": "^2.3.0",
"jstoxml": "^5.0.2",
"lucide-react": "^0.468.0",
"next": "15.1.0",
"next-themes": "^0.4.4",
"nextjs-routes": "^2.2.4",
Expand All @@ -48,6 +48,7 @@
"tailwindcss-animate": "^1.0.7",
"ts-jest": "^29.2.5",
"zod": "^3.23.8",
"zod-prisma-types": "^3.2.1",
"zod-to-json-schema": "^3.22.3"
},
"devDependencies": {
Expand Down
6 changes: 5 additions & 1 deletion prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ datasource db {
url = env("DATABASE_URL")
}

generator zod {
provider = "zod-prisma-types"
}

enum ContentType {
MOVIE
SERIES
Expand Down Expand Up @@ -147,7 +151,7 @@ model Profile {
model SubscriptionType {
id String @id @default(uuid())
type String @unique
priceInEuroCents Int @map("price_in_euro_cents")
priceInEuroCents Int @map("price_in_euro_cents") @default(0)
Subscription Subscription[]
}

Expand Down
13 changes: 9 additions & 4 deletions src/app/api/health/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ import type { NextRequest } from 'next/server';

import { StatusCodes } from 'http-status-codes';

import { ResponseFormatter } from '@/lib/classes/api-responses';
import { ResponseFormatter } from '@/lib/classes/reponse-formatter';

export async function GET(request: NextRequest) {
const requestHeader = request.headers.get('Accept') ?? undefined;

export function GET(request: NextRequest) {
return ResponseFormatter.formatResponse(
{ message: 'OK' },
request.headers.get('Accept') || 'application/json',
{
status: 'healthy',
timestamp: new Date().toISOString(),
},
requestHeader,
StatusCodes.OK,
);
}
35 changes: 35 additions & 0 deletions src/app/api/v1/[route]/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { NextRequest } from 'next/server';

import { ApiRouteHandler } from '@/lib/classes/api-handler';

export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';

export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ route: string; id: string }> },
) {
const { route, id } = await params;

const handler = new ApiRouteHandler(request, route, 'GET', id);
return handler.handleRequest();
}

export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ route: string; id: string }> },
) {
const { route, id } = await params;

const handler = new ApiRouteHandler(request, route, 'PUT', id);
return handler.handleRequest();
}

export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ route: string; id: string }> },
) {
const { route, id } = await params;

const handler = new ApiRouteHandler(request, route, 'DELETE', id);
return handler.handleRequest();
}
Loading

0 comments on commit f127791

Please sign in to comment.