Skip to content
Merged
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
Binary file added lint_results.txt
Binary file not shown.
16 changes: 16 additions & 0 deletions lint_results_utf8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

> learnault-api@0.1.0 lint
> eslint .


C:\Users\EMMA\Desktop\learn\learnault-api\src\config\swagger.ts
1:41 error Extra semicolon semi
37:2 error Extra semicolon semi
39:43 error Extra semicolon semi

C:\Users\EMMA\Desktop\learn\learnault-api\src\controllers\user.controller.ts
1:62 warning 'UpdateWalletData' is defined but never used. Allowed unused vars must match /^I[A-Z]|^_/u @typescript-eslint/no-unused-vars

Γ£û 4 problems (3 errors, 1 warning)
3 errors and 0 warnings potentially fixable with the `--fix` option.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"jsonwebtoken": "^9.0.2",
"morgan": "^1.10.1",
"pg": "^8.20.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.1",
"winston": "^3.19.0",
"zod": "^3.25.76"
},
Expand All @@ -59,6 +61,8 @@
"@types/node": "^22.19.13",
"@types/pg": "^8.18.0",
"@types/supertest": "^7.2.0",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.8",
"@vitest/coverage-v8": "4.0.18",
"eslint": "^10.0.2",
"nodemon": "^3.1.14",
Expand Down
259 changes: 259 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Binary file added server_error.txt
Binary file not shown.
Binary file added server_error_2.txt
Binary file not shown.
86 changes: 86 additions & 0 deletions server_error_2_utf8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
node.exe : C:\Users\EMM
A\Desktop\learn\learnau
lt-api\node_modules\.pn
pm\@prisma+client@7.4.2
_prisma_49b4b128965f74e
a9bbd7586bc0c7d7a\node_
modules\@prisma\client\
src\runtime\getPrismaCl
ient.ts:260
At line:1 char:1
+ & "C:\nvm4w\nodejs/no
de.exe" "C:\Users\EMMA\
AppData\Roaming\npm/nod
e_ ...
+ ~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~~
+ CategoryInfo
: NotSpecifi
ed: (C:\Users\EMMA
\D...maClient.ts:2
60:String) [], Rem
oteException
+ FullyQualifiedEr
rorId : NativeComm
andError

throw new Prism
aClientInitializationEr
ror(
^


PrismaClientInitializat
ionError:
`PrismaClient` needs
to be constructed with
a non-empty, valid
`PrismaClientOptions`:

```
new PrismaClient({
...
})
```

or

```
constructor() {
super({ ... });
}
```

at new t (C:\Users\
EMMA\Desktop\learn\lear
nault-api\node_modules\
.pnpm\@prisma+client@7.
4.2_prisma_49b4b128965f
74ea9bbd7586bc0c7d7a\no
de_modules\@prisma\clie
nt\src\runtime\getPrism
aClient.ts:260:15)
at <anonymous> (C:\
Users\EMMA\Desktop\lear
n\learnault-api\src\con
fig\database.ts:7:42)
at ModuleJob.run (n
ode:internal/modules/es
m/module_job:345:25)
at async onImport.t
racePromise.__proto__ (
node:internal/modules/e
sm/loader:665:26)
at async asyncRunEn
tryPointWithESMLoader (
node:internal/modules/r
un_main:117:5) {
clientVersion:
'7.4.2',
errorCode: undefined,
retryable: undefined
}

Node.js v22.20.0
50 changes: 50 additions & 0 deletions server_error_utf8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
node.exe : C:\Users\EMM
A\Desktop\learn\learnau
lt-api\src\config\datab
ase.ts:1
At line:1 char:1
+ & "C:\nvm4w\nodejs/no
de.exe" "C:\Users\EMMA\
AppData\Roaming\npm/nod
e_ ...
+ ~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~~
+ CategoryInfo
: NotSpecifi
ed: (C:\Users\EMMA
\D...g\database.ts
:1:String) [], Rem
oteException
+ FullyQualifiedEr
rorId : NativeComm
andError

import { PrismaClient
} from '@prisma/client'
^

SyntaxError: The
requested module
'@prisma/client' does
not provide an export
named 'PrismaClient'
at
ModuleJob._instantiate
(node:internal/modules/
esm/module_job:228:21)
at async
ModuleJob.run (node:int
ernal/modules/esm/modul
e_job:337:5)
at async onImport.t
racePromise.__proto__ (
node:internal/modules/e
sm/loader:665:26)
at async asyncRunEn
tryPointWithESMLoader (
node:internal/modules/r
un_main:117:5)

Node.js v22.20.0
16 changes: 12 additions & 4 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import dotenv from 'dotenv'
dotenv.config()

import express from 'express'
import cors from 'cors'
import helmet from 'helmet'
import morgan from 'morgan'
import dotenv from 'dotenv'

import swaggerUi from 'swagger-ui-express'
import { specs } from './config/swagger'
import routes from './routes'
import { errorHandler, notFoundHandler } from './middleware/error.middleware'

dotenv.config()

const app: express.Application = express()

app.use(express.json())
app.use(cors())
app.use(helmet())
app.use(helmet({
contentSecurityPolicy: false, // Disable CSP for Swagger UI to work correctly
}))
app.use(morgan('dev'))

// API routes
app.use('/api', routes)

// Swagger documentation
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs))

// Health check endpoint
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok', timestamp: new Date().toISOString() })
Expand Down
8 changes: 7 additions & 1 deletion src/config/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined
}

const prisma = globalForPrisma.prisma ?? new PrismaClient()
const prisma = globalForPrisma.prisma ?? new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
})

if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
Expand Down
41 changes: 41 additions & 0 deletions src/config/swagger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import swaggerJsdoc from 'swagger-jsdoc'


const options: swaggerJsdoc.Options = {
definition: {
openapi: '3.0.0',
info: {
title: 'Learnault API Documentation',
version: '1.0.0',
description: 'Comprehensive API documentation for Learnault - a decentralized learn-to-earn platform on Stellar',
contact: {
name: 'Learnault Contributors',
url: 'https://github.com/learnault/learnault',
},
},
servers: [
{
url: '/api',
description: 'Main API base path',
},
],
components: {
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
},
},
},
security: [
{
bearerAuth: [],
},
],
},
apis: ['./src/controllers/**/*.ts', './src/docs/*.ts'], // Path to the API docs
}

export const specs = swaggerJsdoc(options)

65 changes: 56 additions & 9 deletions src/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,30 @@ const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '1d'

export class AuthController {
/**
* @route POST /api/v1/auth/register
* @desc Register a new user
* @access Public
* @openapi
* /auth/register:
* post:
* summary: Register a new user
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/RegisterInput'
* responses:
* 201:
* description: User registered successfully
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/AuthResponse'
* 400:
* description: Validation failed
* 409:
* description: User already exists
* 500:
* description: Internal server error
*/
async register(req: Request, res: Response): Promise<void> {
try {
Expand Down Expand Up @@ -79,9 +100,30 @@ export class AuthController {
}

/**
* @route POST /api/v1/auth/login
* @desc Login a user
* @access Public
* @openapi
* /auth/login:
* post:
* summary: Login a user
* tags: [Auth]
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/LoginInput'
* responses:
* 200:
* description: Login successful
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/AuthResponse'
* 400:
* description: Validation failed
* 401:
* description: Invalid credentials
* 500:
* description: Internal server error
*/
async login(req: Request, res: Response): Promise<void> {
try {
Expand Down Expand Up @@ -143,9 +185,14 @@ export class AuthController {
}

/**
* @route POST /api/v1/auth/logout
* @desc Logout user (client-side usually handles this by deleting token, but can track server-side)
* @access Private (optional, here public)
* @openapi
* /auth/logout:
* post:
* summary: Logout user
* tags: [Auth]
* responses:
* 200:
* description: Logged out successfully
*/
async logout(req: Request, res: Response): Promise<void> {
// For stateless JWT, we can't truly "logout" unless we blacklist tokens.
Expand Down
Loading
Loading