Feature/Use fastify instead of express (#1)

- Replaced Apollo Server with Mercurius for GraphQL API
- Updated resolvers to use Mercurius-compatible GraphQL implementation
- Migrated from Express to Fastify for server framework
- Improved error handling with GraphQL error extensions
- Added Zod for environment variable validation
- Updated Prisma schema and migrations
- Configured CORS and WebSocket subscriptions
- Simplified GraphQL schema and resolver structure
- Enhanced type safety and code organization
- Replaced Apollo Server with Mercurius for GraphQL API
- Updated resolvers to use Mercurius-compatible GraphQL implementation
- Migrated from Express to Fastify for server framework
- Improved error handling with GraphQL error extensions
- Added Zod for environment variable validation
- Updated Prisma schema and migrations
- Configured CORS and WebSocket subscriptions
- Simplified GraphQL schema and resolver structure
- Enhanced type safety and code organization

Reviewed-on: #1
Co-authored-by: Jusemon <juansmm@outlook.com>
Co-committed-by: Jusemon <juansmm@outlook.com>
This commit is contained in:
Juan Sebastián Montoya 2025-03-06 19:15:56 -05:00 committed by Juan Sebastián Montoya
parent b4e5a04126
commit 6214b503bc
47 changed files with 4968 additions and 5424 deletions

View file

@ -28,7 +28,7 @@ function App() {
// Call checkAuth on component mount
checkAuth();
const handleLoginSuccess = (token: string, id: string) => {
const handleLoginSuccess = (_: string, id: string) => {
setIsAuthenticated(true);
setUserId(id);
};

View file

@ -79,17 +79,23 @@ export function RoomList(props: RoomListProps) {
});
// Subscribe to new rooms
const [roomAddedSubscription] = createSubscription({
const [roomAddedSubscription] = createSubscription<{
roomAdded: Room;
}>({
query: ROOM_ADDED_SUBSCRIPTION,
});
// Subscribe to room updates (when members change)
const [roomUpdatedSubscription] = createSubscription({
const [roomUpdatedSubscription] = createSubscription<{
roomUpdated: Room;
}>({
query: ROOM_UPDATED_SUBSCRIPTION,
});
// Join room mutation
const [joinRoomResult, joinRoom] = createMutation(JOIN_ROOM_MUTATION);
const [joinRoomResult, joinRoom] = createMutation<{
joinRoom: Room;
}>(JOIN_ROOM_MUTATION);
// Load initial rooms
createEffect(() => {
@ -150,7 +156,7 @@ export function RoomList(props: RoomListProps) {
setRooms((prev) =>
prev.map((room) =>
room.id === roomId
? { ...room, members: result.data.joinRoom.members }
? { ...room, members: result.data!.joinRoom.members }
: room
)
);

View file

@ -1,8 +1,8 @@
/* @refresh reload */
import { render } from 'solid-js/web'
import './index.css'
import App from './App.tsx'
import { render } from 'solid-js/web';
import './index.css';
import App from './App.tsx';
const root = document.getElementById('root')
const root = document.getElementById('root');
render(() => <App />, root!)
render(() => <App />, root!);

View file

@ -1,16 +1,20 @@
import { z } from 'zod';
import { createClient, fetchExchange, subscriptionExchange } from '@urql/core';
import { createClient as createWSClient } from 'graphql-ws';
import { createClient as createWsClient } from 'graphql-ws';
// Get API URLs from environment variables
const API_URL =
import.meta.env.VITE_API_URL || 'https://chat-api.jusemon.com/graphql';
const WS_URL =
import.meta.env.VITE_WS_URL || 'wss://chat-api.jusemon.com/graphql';
const envSchema = z
.object({ VITE_API_URL: z.string(), VITE_WS_URL: z.string() })
.transform((env) => ({
API_URL: env.VITE_API_URL,
WS_URL: env.VITE_WS_URL,
}));
const { API_URL, WS_URL } = envSchema.parse(import.meta.env);
console.log('Current API_URL', API_URL);
console.log('Current WS_URL', WS_URL);
// Create a WebSocket client for GraphQL subscriptions
const wsClient = createWSClient({
const wsClient = createWsClient({
url: WS_URL,
});
@ -23,11 +27,8 @@ export const client = createClient({
forwardSubscription: (operation) => ({
subscribe: (sink) => {
const dispose = wsClient.subscribe(
{
...operation,
query: operation.query || '',
},
sink as any
{ ...operation, query: operation.query || '' },
sink
);
return {
unsubscribe: dispose,

View file

@ -1 +1,10 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_WS_URL: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}