Migrate exchange backend from Django to Express + Apollo Server + Prisma
Build Docker Image / build (push) Successful in 1m54s

Replace Python/Django/Graphene with TypeScript/Express/Apollo Server.
Same 4 endpoints (public/user/team/m2m), same JWT auth.
Prisma replaces Django ORM for Offer/Request/SupplierProfile.
Temporal and Odoo integrations preserved.
This commit is contained in:
Ruslan Bakiev
2026-03-09 09:20:37 +07:00
parent 569924cabb
commit 27b86c85b7
108 changed files with 5024 additions and 3918 deletions
+58
View File
@@ -0,0 +1,58 @@
import express from 'express'
import cors from 'cors'
import { ApolloServer } from '@apollo/server'
import { expressMiddleware } from '@apollo/server/express4'
import * as Sentry from '@sentry/node'
import { publicTypeDefs, publicResolvers } from './schemas/public.js'
import { userTypeDefs, userResolvers } from './schemas/user.js'
import { teamTypeDefs, teamResolvers } from './schemas/team.js'
import { m2mTypeDefs, m2mResolvers } from './schemas/m2m.js'
import { publicContext, userContext, teamContext, m2mContext, type AuthContext } from './auth.js'
const PORT = parseInt(process.env.PORT || '8000', 10)
const SENTRY_DSN = process.env.SENTRY_DSN || ''
if (SENTRY_DSN) {
Sentry.init({
dsn: SENTRY_DSN,
tracesSampleRate: 0.01,
release: process.env.RELEASE_VERSION || '1.0.0',
environment: process.env.ENVIRONMENT || 'production',
})
}
const app = express()
app.use(cors({ origin: ['https://optovia.ru'], credentials: true }))
const publicServer = new ApolloServer<AuthContext>({ typeDefs: publicTypeDefs, resolvers: publicResolvers, introspection: true })
const userServer = new ApolloServer<AuthContext>({ typeDefs: userTypeDefs, resolvers: userResolvers, introspection: true })
const teamServer = new ApolloServer<AuthContext>({ typeDefs: teamTypeDefs, resolvers: teamResolvers, introspection: true })
const m2mServer = new ApolloServer<AuthContext>({ typeDefs: m2mTypeDefs, resolvers: m2mResolvers, introspection: true })
await Promise.all([publicServer.start(), userServer.start(), teamServer.start(), m2mServer.start()])
app.use('/graphql/public', express.json(), expressMiddleware(publicServer, {
context: async () => publicContext(),
}) as unknown as express.RequestHandler)
app.use('/graphql/user', express.json(), expressMiddleware(userServer, {
context: async ({ req }) => userContext(req as unknown as import('express').Request),
}) as unknown as express.RequestHandler)
app.use('/graphql/team', express.json(), expressMiddleware(teamServer, {
context: async ({ req }) => teamContext(req as unknown as import('express').Request),
}) as unknown as express.RequestHandler)
app.use('/graphql/m2m', express.json(), expressMiddleware(m2mServer, {
context: async () => m2mContext(),
}) as unknown as express.RequestHandler)
app.get('/health', (_, res) => { res.json({ status: 'ok' }) })
app.listen(PORT, '0.0.0.0', () => {
console.log(`Exchange server ready on port ${PORT}`)
console.log(` /graphql/public - public`)
console.log(` /graphql/user - id token auth`)
console.log(` /graphql/team - team access token auth`)
console.log(` /graphql/m2m - internal services (no auth)`)
})