Skip to content
Open
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
2 changes: 2 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/sh
export PATH="$HOME/.nvm/versions/node/v20.11.0/bin:$PATH"

. "$(dirname "$0")/_/husky.sh"

yarn lint-staged --verbose
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<br />
</div>

# 🏗🔴 Scaffold-OP
# 🏗🔴 Ceptor-Games-Scaffold

<h4 align="center">
<a href="https://docs.scaffoldeth.io">Documentation</a> |
Expand Down
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"workspaces": {
"packages": [
"packages/hardhat",
"packages/nextjs"
"packages/nextjs",
"packages/backend"
]
},
"scripts": {
Expand Down Expand Up @@ -36,7 +37,14 @@
},
"packageManager": "yarn@3.2.3",
"devDependencies": {
"@types/react": "^18",
"@types/react-dom": "^18",
"husky": "^8.0.1",
"lint-staged": "^13.0.3"
},
"dependencies": {
"next-auth": "^4.24.7",
"react": "^18.3.1",
"react-dom": "^18.3.1"
}
}
1 change: 1 addition & 0 deletions packages/backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# backend
17 changes: 17 additions & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "backend",
"packageManager": "yarn@3.2.3",
"dependencies": {
"express": "^4.19.2",
"mongoose": "^8.3.5"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/mongoose": "^5.11.97",
"ts-node-dev": "^2.0.0",
"typescript": "^5.4.5"
},
"scripts": {
"start": "ts-node-dev --respawn --transpile-only src/server.ts"
}
}
13 changes: 13 additions & 0 deletions packages/backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import express from 'express';
import campaignRoutes from './routes/campaignRoutes';
import characterRoutes from './routes/characterRoutes';
import sessionRoutes from './routes/sessionRoutes';

const app = express();

app.use(express.json());
app.use('/campaigns', campaignRoutes);
app.use('/characters', characterRoutes);
app.use('/sessions', sessionRoutes);

export default app;
112 changes: 112 additions & 0 deletions packages/backend/src/controllers/campaignController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Request, Response } from 'express';
import { Campaign } from '../models/Campaign';

export const createCampaign = async (req: Request, res: Response) => {
const { worldId, ccId } = req.body;
try {
const world = await World.findById(worldId);
if (!world) {
return res.status(404).json({ message: 'World not found' });
}
if (world.ccId !== ccId && !world.permissions.includes(ccId)) {
return res.status(403).json({ message: 'Not authorized to create campaign in this world' });
}
const newCampaign = new Campaign(req.body);
await newCampaign.save();
res.status(201).json(newCampaign);
} catch (error) {
res.status(400).json({ message: error.message });
}
};

export const getCampaignById = async (req: Request, res: Response) => {
try {
const campaign = await Campaign.findOne({ externalId: req.params.id });
if (!campaign) {
return res.status(404).json({ message: 'Campaign not found' });
}
res.status(200).json(campaign);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const updateCampaign = async (req: Request, res: Response) => {
try {
const updatedCampaign = await Campaign.findOneAndUpdate({ externalId: req.params.id }, req.body, { new: true });
if (!updatedCampaign) {
return res.status(404).json({ message: 'Campaign not found' });
}
res.status(200).json(updatedCampaign);
} catch (error) {
res.status(400).json({ message: error.message });
}

export const deleteCampaign = async (req: Request, res: Response) => {
try {
const deletedCampaign = await Campaign.findOneAndDelete({ externalId: req.params.id });
if (!deletedCampaign) {
return res.status(404).json({ message: 'Campaign not found' });
}
res.status(200).json({ message: 'Campaign deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}

export const listCampaigns = async (req: Request, res: Response) => {
const { name, worldId, ccId, numCharacters, frequency } = req.query;
try {
const query = {};
if (name) query.name = name;
if (worldId) query.worldId = worldId;
if (ccId) query.ccId = ccId;
if (numCharacters) query.numCharacters = numCharacters;
if (frequency) query.frequency = frequency;

const campaigns = await Campaign.find(query);
res.status(200).json(campaigns);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const listCampaignsByWorld = async (req: Request, res: Response) => {
const { worldExternalId } = req.query;

try {
// Find the world by its externalId
const world = await World.findOne({ externalId: worldExternalId });
if (!world) {
return res.status(404).json({ message: 'World not found' });
}

// Find campaigns associated with the world's _id
const campaigns = await Campaign.find({ worldId: world._id });

// Send the list of campaigns in the response
res.status(200).json(campaigns);
} catch (error) {
// Handle any errors that occur during the process
res.status(500).json({ message: error.message });
}
};

// Example mock data for campaigns
const mockCampaigns = [
{
_id: '1',
name: 'The Quest for the Holy Grail',
description: 'Embark on an epic quest to find the legendary Holy Grail.',
externalId: 'campaign-1',
worldId: '1',
// ... other properties ...
},
// ... more mock campaigns ...
];

// Serve mock data in your API route
export const listCampaigns = async (req: Request, res: Response) => {
const { worldId } = req.query;
const filteredCampaigns = mockCampaigns.filter(campaign => campaign.worldId === worldId);
res.status(200).json(filteredCampaigns);
};
57 changes: 57 additions & 0 deletions packages/backend/src/controllers/characterController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Request, Response } from 'express';
import { Character } from '../models/Character';

export const createCharacter = async (req: Request, res: Response) => {
try {
const newCharacter = new Character(req.body);
await newCharacter.save();
res.status(201).json(newCharacter);
} catch (error) {
res.status(400).json({ message: error.message });
}
};

export const getCharacterById = async (req: Request, res: Response) => {
try {
const character = await Character.findById(req.params.id);
if (!character) {
return res.status(404).json({ message: 'Character not found' });
}
res.status(200).json(character);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const updateCharacter = async (req: Request, res: Response) => {
try {
const updatedCharacter = await Character.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!updatedCharacter) {
return res.status(404).json({ message: 'Character not found' });
}
res.status(200).json(updatedCharacter);
} catch (error) {
res.status(400).json({ message: error.message });
}
};

export const deleteCharacter = async (req: Request, res: Response) => {
try {
const deletedCharacter = await Character.findByIdAndDelete(req.params.id);
if (!deletedCharacter) {
return res.status(404).json({ message: 'Character not found' });
}
res.status(200).json({ message: 'Character deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const listCharacters = async (req: Request, res: Response) => {
try {
const characters = await Character.find({});
res.status(200).json(characters);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
Empty file.
69 changes: 69 additions & 0 deletions packages/backend/src/controllers/sessionController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Request, Response } from 'express';
import { Session } from '../models/Session';

export const createSession = async (req: Request, res: Response) => {
try {
const newSession = new Session(req.body);
await newSession.save();
res.status(201).json(newSession);
} catch (error) {
res.status(400).json({ message: error.message });
}
};

export const getSessionById = async (req: Request, res: Response) => {
try {
const session = await Session.findById(req.params.id);
if (!session) {
return res.status(404).json({ message: 'Session not found' });
}
res.status(200).json(session);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const updateSession = async (req: Request, res: Response) => {
try {
const updatedSession = await Session.findByIdAndUpdate(req.params.id, req.body, { new: true });
if (!updatedSession) {
return res.status(404).json({ message: 'Session not found' });
}
res.status(200).json(updatedSession);
} catch (error) {
res.status(400).json({ message: error.message });
}
};

export const deleteSession = async (req: Request, res: Response) => {
try {
const deletedSession = await Session.findByIdAndDelete(req.params.id);
if (!deletedSession) {
return res.status(404).json({ message: 'Session not found' });
}
res.status(200).json({ message: 'Session deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const listSessions = async (req: Request, res: Response) => {
try {
const sessions = await Session.find({});
res.status(200).json(sessions);
} catch (error) {
res.status(500).json({ message: error.message });
}
};

export const getSessionDetails = async (req: Request, res: Response) => {
try {
const session = await Session.findOne({ externalId: req.params.externalId }).populate('characters');
if (!session) {
return res.status(404).json({ message: 'Session not found' });
}
res.status(200).json(session);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
Loading